* added multi select back * (WIP): Complete the dynamc height update logic * (WIP): Dynamic height logic * (WIP): Container computation logic, Next steps: Prevent reflow when resize is disabled. Fix logic of widgets randomly changing positions (Debug) * Fix logic in container computations * Integrate for PoC * fixed the no initial load dynamic height updates * Stop vertical resize and reflow when dynamic height is enabled for a widget * added another container in text widget * enabled dynamic height for container widgets * removed dynamic height feature from list widget * Fixed Button and Input components height increase * added an experiment to overflow the content if maxHEight is less * removed the ref of Textwidget by mistake, added it back * fixed text widget height overflow problem with a little hack * added long labels with text * fixed the table scroll issue * overflow fixed for json form widget * added extra 8px height for Switch, Rating and Checkbox Height * (WIP): Resolve issues * (WIP): Fix widget padding issue * added overflow container for Radio and Switch group widgets * (WIP): Have modals work with dynamic height * added the overlay and the handles * added dragging behavior to the dots * fixed the overlapping with the selection tool * (WIP): Fix issues reported * now we can update the property pane values back from overlay handles * now we can update the property pane values back from overlay handles * (WIP): Fix table widget * Fix package.json * Remove unit tests temporarily * Fix unit test * (WIP): Fix modal resize. Fix cursors. Fix border issue on non-resizable widgets * fetch component heights using the requestAnimationFrame callback * behavioural changes * (WIP): Fix issues on the platform * Update main container size appropriately * more behavioural changes * overlay now only be visible when hovering over the dots * grid showing and widget reselecting * added onfocus and onblur events to property pane listeners * added onfocus and onblur events to property pane listeners * added a range slider for min and max * added demarcations for slider values * (WIP): Fix platform workflows for dynamic height * Fix issues with widgets * Fix removed import * - Add missing cypress files * set the limits * limit increase on change * Fix z-index of min max limit indicators. Fix unused-vars warnings * Fix Table Widget and Text Widget issues * Fix: all the bugs in the bug master list for DH (#16268) * changed the zindex for the signifiers * showing signifiers only when the widget is selected * made changes suggested by Momcilo * activate the dots when the fields are active * created a new centered dot handle * removed overlays on focus and made the border more like deisgn * handles on top of other widgets * hide the overlay when multiple widgets are selected * added a white border * added a white border * bug #15509 resolved * changed the minDynamicHeightLimit to 2 instead of 4 to fix the Bug #15527 * removed the height auto fix from BaseInputComponent to fix the Bug #15388 * removed the condition to not ccalculate dynamic height when the row difference is less than 2 to fix the bug 15353 * made fixes for the bug #16307 * made fixes for the bug #16308 * made fixes for bug 16310 * made fixes for the bug #16402 * removed some log statements * made fixes for the bug #16407 * fixed label problem found in the issue #16543 * made fixes for the issue #16547 * made fixes for the bug #16492 * redeploy * (WIP): Fix to make this branch functional * imported LabelWithTooltip back from design system * signifier is now centered * filled the signifier with primary color * overlay hidden while dragging * made the signifier dashed border also draggable * Fix issue #16590 (#16798) * set the limits to 4 rows * replaced the static 40 value * added signifiers for modal widget * added signifiers for modal widget * tried solving the scroll issue for widgets when there are limits * solved the height problem using ResizeObserver * (WIP): Fix maxDynamicHeight issue with container widgets: * made the changes as per the review * fixed the issue for input widget when label gets out of border * hide text widget overflow options if auto height is enabled * (WIP): In view mode, invisible widgets now donot take space (#16920) * (WIP): In view mode, invisible widgets now donot take space * (WIP): Enable the feature where invisible widgets in view mode don't take space to all widgets irrespective of the dynamic height feature * Remove Replay conditional * removed the scroll container for container type widgets * removed the scroll container for container type widgets * updated the hook to set overflow none for text widget * fixed the should dynamic height logic to respect the min height limit * Modal widget adheres to dynamic height (#16995) * Modal widget adheres to dynamic height * WIP: POC: fix dynamic height issues (#16996) Fix height less than 4 issue. Fix JSONForm adherence to min and max height * POC: Dynamic height undo redo issue (#17085) * Revert debouce timeout * (WIP): Fix issue with undo-redo in dynamic height * fix: Dynamic height issue fixes (#17153) * Dynamic height issue fixes == - Fix issue where nested widgets did not ensure parent dynamic height updates - Fix issue where Modal widget updates came in subsequent renders - Fix issue where JSONForm collapses - Fix performance issue for independent updates * Use functions to get min and max dynamic height * Fix issue where variable might have been undefined * added the dynamic container into the deploy mode as well * added overflow-x hidden when overflow-y is active in the dynamic height container * fix: Dynamic height Issue fixes (#17204) Fix preview mode invisible widgets. Fix Tabs widget dynamic height. * removed a console.log statement * removed the slider control file * imported the LabelWithTooltip from the repo rather than ds * word-break CSS rules added for Switch and Checkbox widget when Dynamic Height is enabled * abstracted the check for dynamic height with limits enabled as isDynamicHeightWithLimitsEnabledForWidget * abstracted the static value of 10 in dynamic height overlay to GridDefaults * abstracted min and max dynamic height limits to getters * fix: replaced all the refs for simpler widgets (#17353) * replaced all the refs for simpler widgets * removed the updateDynamicHeight from componentDidUpdate in BaseWidget * added back lifecycle methods back to BaseWidget * removed the contentRef from SwitchGroup and Table * updating the height from the auto height with limits as well * some hacks to make the limits work * working solution * used setTimeout to send an update to updateDynamicHeight from overlay update * removed a log * added requestanimationframe in settimeout Co-authored-by: Ankur Singhal <ankursinghal@Ankurs-MacBook-Pro-2.local> Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * Fix issues caused during merge * Remove unneeded derived property * removed more unnecessary code which should have been removed after removing the ref dependency * fixed the maxDynamicHeight issue * Fix issue where property configs were not being sent * fix: Auto Height Feature - add selectors for tests (#17687) Add selectors for auto height cypress tests * fix: removed height auto default theme (#17415) removed height auto css rule from the default theme Co-authored-by: Ankur Singhal <ankursinghal@Ankurs-MacBook-Pro-2.local> * fix: Auto Height Feature - Resolve issues and restructure code (#17686) * Fix issues in dynamic height. Restructure code and reduce abstraction leaks * Fix typescript issues * Update based on review comments. Comment migrations, as a cyclic import is causing the jest tests to fail. * Remove unused imports * Decrease code nesting * added the base styles for the overlay like position and z-index in its styled component css * used the isDynamicHeightEnabled prop to set the height of SwitchGroup and RadioGroup widgets from 32px to 100% in case of inline mode * fix: Auto Height - Resolve issues (#17737) * Fix Tabs Widget showTabs toggle based auto height. Revert removal of BaseWidget code. Remove box-intersect and use a bruteforce algorithm. Add base logic for having containers collapse due to hidden child widgets * Hide scroll contents and overflow property pane controls when dynamic height is enabled * Removed the class property expectedHeight from BaseWidget as it is not useful in the overlay logic after some changes * fixed the left alignment issue of label in the rich text editor by adding some styles applied only when the dynamic height is enabled * fixed the input field stretching issue in case of Dynamic height by adding some CSS styles when isDynamicHeight is true * Fix failing modal widget cypress tests * Fix issue with scrollContents and Tabs Widget defaulTab * added a little bit padding of 4px to the right of scroll container of dynamic height with limit * Add test locators for resize handles * removed the dynamic height logic from the table widget * fix: Auto-Height invisible widgets (#17849) * Fix issue where invisible widgets were still taking space * Make sure to collapse only if dynamic height is enabled * Fix issues with reflow (not the invisible widgets) * Fix container min height issues * Fix reflow with original bottom and top values. Testing needed * Fix invisible widgets * fix: enabled dynamic height for stat box widget (#17971) enabled dynamic height for stat box widget Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: added a min height to rich text editor so that it does not collapse (#17970) added a min height to rich text editor so that it does not collapse Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * Fix issue with resizing auto height widget * Add helper text to educate users regarding the scroll disconnect in WYSIWYG * fix: Auto Height Fixes (#18111) AUTO HEIGHT FIXES - Fix JSONForm height discrepancy - Fix issue where widgets moved below the other - Fix droptarget height after parent container resize * fix: sliced up the DynamicHeightOverlay component a little bit (#18100) * sliced up the DynamicHeightOverlay component a little bit * more refactoring * more refactoring * used release event emitter and refactored more Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: rich text editor center alignment issue (#18142) * removed the center alignment from rich text editor * dummy commit Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: old DSL container collapse (#18160) * Fix issue where old containers from old DSLs used to collapse when auto height was enabled * Fix issue where old containers don't allow new widgets to be added when auto height is enabled, this is because the shouldScrollContents is undefined * fix: input widgets issue (#18172) fixed the auto height not working issue Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: preview deploy mode (#18174) fixed the preview and deploy mode Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: auto height limits label intersection with handle dot (#18186) fixed the position of the limits label to the right so that it will not intersect with the handle dot Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: auto height limits rich text editor min height (#18187) decrease the min height of the RTE so that it does not have the boundary issue with the max limit when auto height with limits is enabled Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: grammatical error in the help text (#18188) changed react to reacts in the helpText of the dynamic height property in the proeprty pane Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: auto height tabs double scroll (#18210) solved the issue by disabling the scroll for the child canvas widget in the tabs widget Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: auto height limits resizing (#18213) * fixed the auto height limits resizing issue * made the auto height overlay independent of isResizing and used its own property to show the grid * some more refactoring Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * dummy commit * fix: old apps container issue (#18255) filtered out the widgets which are detached from layout Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: fixing auto height in childless containers. (#18263) fixing auto height in childless containers. * task: Dynamic height reflow fixes in Branch (#18244) dynamic height reflow fixes * fix: compact label issue and min and max limits numeric input (#18282) fixed compact label issue and turned min and max limits to numeric input Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: LabelWithTooltip help icon fix * fix: NaN and min limit for min and max (#18284) * fixed compact label issue and turned min and max limits to numeric input * fixed NaN and set min to be 4 Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: validation issues for min max (#18286) * fixed compact label issue and turned min and max limits to numeric input * fixed NaN and set min to be 4 * validations start working min max Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * added a full stop to container scroll helper text * validations start working min max * dummy commit * feat: stop resizing auto height widgets vertically because of Drag n Drop Reflow (#18267) * reflow fixes * stop resizing auto height widgets vertically because of Drag n Drop Reflow * feat: Analytics for Dynamic height (#18279) * Fix canvas min height issue and invisible widgets issue and remove logs and fix issue where widgets overlapped when coming back from preview mode to edit mode * Fix issue with containers not respecting auto height and decreasing height * Fix issue with modal widget not hugging contents, and container widgets never become visible after going invisible * Fix issue where existing containers don't have correct min height for child canvas * fix: canvasLevelsReducers test (#18301) fixed the canvasLevelsReducers test Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: removed auto height min max config from widget features (#18316) removed auto height min max config from widget features Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: Fixing Modal Height updates (#18317) Fixing Modal Height updates * fix: text widget background auto height (#18319) added background color of Text widget back to the auto height container Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * test: cypress tests for auto height (#17676) * Added tests for dynamic height * updated tests for another usecase * moved locators into commonfile * updated common method * added tests for some more widgets * Added tests for jsonForm / Form widget * Updated the test * updated test for multiple text widgets * updated test with few more usecases * updated the dsl * updated tests for text change * updated tests based on new changes * updated cypress test fixes * fix: auto height container merge poc wrt release (#18334) updated the poc wrt PR already merged in the release regarding the auto height container Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: renamed auto height overlay components and added some tests (#18333) * renamed auto height overlay components and added some tests * replaced the 10 value with GridDefaults * avoiding event to reach drop target Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * updated tests * Merge all code into one branch * Fix failing AutoHeightcontainer test * fix: Fix reflow computations which were causing widget overlap (#18300) * Fix reflow computations which were causing widget overlap * Fix issues with parent container height and overlapping widgets * Remove console logs * Revert comment * Fix issues related to reflow of containers * feat: Making getEffectedBoxes a Recursive function in autoHeight Reflow (#18336) Making getEffectedBoxes a Recursive function in autoHeight Reflow * Return null for invisible widgets from withWidgetProps * Remove duplicate import Co-authored-by: rahulramesha <71900764+rahulramesha@users.noreply.github.com> * Remove missed console log * fix: Label position gets deselected on selecting already selected option (#18298) * fix: Label position gets deselected on selecting the already selected value * Added migration for Currency & Phone input widgets * simplify migration function using a utility * combine conditions * Increments LATEST_PAGE_VERSION * Update DynamicHeight_Visibility_spec.js updated a check wrt auto height * Handling Modals for canvas size calculations * fix: migrate label position test failing issue (#18365) fixed migrate label postition test failing issue Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * removed the two unwanted imports from DSLMigrations to fix client build * fix: Auto height zero and limits issue (#18366) fixed the auto height zero and limits issue Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> * fix: Auto height regression issues (#18367) * Fix auto height regression issues #18367 * feat: auto height migrations (#18368) Add auto height migrations * Increase file caching size * Use manual array for list of auto height enabled widgets * Fix cypress test dsl versions * Revert changes to shouldUpdateHeightDynamically * Update test results based on code changes * Marginally increase the workbox file size cache * review comment incorporated for test spec * Update container auto height property on drop * added small wait for validation Co-authored-by: Ankur Singhal <ankur@appsmith.com> Co-authored-by: rahulramesha <rahul@appsmith.com> Co-authored-by: Abhinav Jha <zatanna@Abhinavs-iMac.lan> Co-authored-by: Ankur Singhal <ankursinghal@Ankurs-MacBook-Pro-2.local> Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com> Co-authored-by: Ashok Kumar M <35134347+marks0351@users.noreply.github.com> Co-authored-by: rahulramesha <71900764+rahulramesha@users.noreply.github.com> Co-authored-by: Albin <albin@appsmith.com> Co-authored-by: Aswath K <aswath.sana@gmail.com> Co-authored-by: NandanAnantharamu <67676905+NandanAnantharamu@users.noreply.github.com> Co-authored-by: Apple <nandan@thinkify.io>
699 lines
22 KiB
TypeScript
699 lines
22 KiB
TypeScript
import {
|
|
ButtonBorderRadiusTypes,
|
|
ButtonVariantTypes,
|
|
} from "components/constants";
|
|
import { PropertyHookUpdates } from "constants/PropertyControlConstants";
|
|
import {
|
|
RenderModes,
|
|
TextSizes,
|
|
WidgetHeightLimits,
|
|
} from "constants/WidgetConstants";
|
|
import { remove } from "lodash";
|
|
import { getTheme, ThemeMode } from "selectors/themeSelectors";
|
|
import { WidgetProps } from "./BaseWidget";
|
|
import { rgbaMigrationConstantV56 } from "./constants";
|
|
import {
|
|
borderRadiusUtility,
|
|
replaceRgbaMigrationConstant,
|
|
boxShadowMigration,
|
|
boxShadowUtility,
|
|
fontSizeUtility,
|
|
lightenColor,
|
|
composePropertyUpdateHook,
|
|
sanitizeKey,
|
|
shouldUpdateWidgetHeightAutomatically,
|
|
isAutoHeightEnabledForWidget,
|
|
getWidgetMaxAutoHeight,
|
|
getWidgetMinAutoHeight,
|
|
} from "./WidgetUtils";
|
|
import {
|
|
getCustomTextColor,
|
|
getCustomBackgroundColor,
|
|
getCustomHoverColor,
|
|
} from "./WidgetUtils";
|
|
|
|
const tableWidgetProps = {
|
|
dynamicBindingPathList: [
|
|
{
|
|
key: "primaryColumns.action.boxShadowColor",
|
|
},
|
|
],
|
|
primaryColumns: {
|
|
action: {
|
|
boxShadow: "0px 0px 4px 3px rgba(0, 0, 0, 0.25)",
|
|
boxShadowColor: ["red", "red", "red"],
|
|
},
|
|
},
|
|
};
|
|
|
|
describe("validate widget utils button style functions", () => {
|
|
const theme = getTheme(ThemeMode.LIGHT);
|
|
// validate getCustomTextColor function
|
|
it("getCustomTextColor - validate empty or undefined background color", () => {
|
|
// background color is undefined
|
|
const result = getCustomTextColor(theme);
|
|
expect(result).toStrictEqual("#FFFFFF");
|
|
|
|
// background color is empty string
|
|
const backgroundColor = "";
|
|
const expected = "#FFFFFF";
|
|
const result2 = getCustomTextColor(theme, backgroundColor);
|
|
expect(result2).toStrictEqual(expected);
|
|
});
|
|
|
|
it("getCustomTextColor - validate text color in case of dark or light background color", () => {
|
|
// background color is dark
|
|
const blueBackground = "#3366FF";
|
|
const expected1 = "#FFFFFF";
|
|
const result1 = getCustomTextColor(theme, blueBackground);
|
|
expect(result1).toStrictEqual(expected1);
|
|
|
|
// background color is light
|
|
const yellowBackground = "#FFC13D";
|
|
const expected2 = "#FFFFFF";
|
|
const result2 = getCustomTextColor(theme, yellowBackground);
|
|
|
|
expect(result2).toStrictEqual(expected2);
|
|
});
|
|
|
|
// validate getCustomBackgroundColor function
|
|
it("getCustomBackgroundColor - validate empty or undefined background color", () => {
|
|
const expected = "none";
|
|
const result = getCustomBackgroundColor();
|
|
expect(result).toStrictEqual(expected);
|
|
});
|
|
|
|
it("getCustomBackgroundColor - validate background color with primary button variant", () => {
|
|
const backgroundColor = "#03b365";
|
|
const expected = "#03b365";
|
|
const result = getCustomBackgroundColor(
|
|
ButtonVariantTypes.PRIMARY,
|
|
backgroundColor,
|
|
);
|
|
expect(result).toStrictEqual(expected);
|
|
});
|
|
|
|
it("getCustomBackgroundColor - validate background color with secondary button variant", () => {
|
|
const backgroundColor = "#03b365";
|
|
const expected = "none";
|
|
const result = getCustomBackgroundColor(
|
|
ButtonVariantTypes.SECONDARY,
|
|
backgroundColor,
|
|
);
|
|
expect(result).toStrictEqual(expected);
|
|
});
|
|
|
|
// validate getCustomHoverColor function
|
|
it("getCustomHoverColor - validate empty or undefined background color or variant", () => {
|
|
// background color and variant is both are undefined
|
|
const expected = "hsl(0, 0%, 95%)";
|
|
const result = getCustomHoverColor(theme);
|
|
expect(result).toStrictEqual(expected);
|
|
|
|
// variant is undefined
|
|
const backgroundColor = "#03b365";
|
|
const expected1 = "hsl(153, 97%, 31%)";
|
|
const result1 = getCustomHoverColor(theme, undefined, backgroundColor);
|
|
expect(result1).toStrictEqual(expected1);
|
|
});
|
|
|
|
// validate getCustomHoverColor function
|
|
it("getCustomHoverColor - validate hover color for different variant", () => {
|
|
const backgroundColor = "hsl(153, 97% ,36%)";
|
|
// variant : PRIMARY
|
|
const expected1 = "hsl(153, 97%, 31%)";
|
|
const result1 = getCustomHoverColor(
|
|
theme,
|
|
ButtonVariantTypes.PRIMARY,
|
|
backgroundColor,
|
|
);
|
|
|
|
expect(result1).toStrictEqual(expected1);
|
|
|
|
// variant : PRIMARY without background
|
|
const expected2 = "hsl(0, 0%, 95%)";
|
|
const result2 = getCustomHoverColor(theme, ButtonVariantTypes.PRIMARY);
|
|
expect(result2).toStrictEqual(expected2);
|
|
|
|
// variant : SECONDARY
|
|
const expected3 = "rgba(3, 181, 101, 0.1)";
|
|
const result3 = getCustomHoverColor(
|
|
theme,
|
|
ButtonVariantTypes.SECONDARY,
|
|
backgroundColor,
|
|
);
|
|
|
|
expect(result3).toStrictEqual(expected3);
|
|
|
|
// variant : SECONDARY without background
|
|
const expected4 = "rgba(255, 255, 255, 0.1)";
|
|
const result4 = getCustomHoverColor(theme, ButtonVariantTypes.SECONDARY);
|
|
expect(result4).toStrictEqual(expected4);
|
|
|
|
// variant : TERTIARY
|
|
const expected5 = "rgba(3, 181, 101, 0.1)";
|
|
const result5 = getCustomHoverColor(
|
|
theme,
|
|
ButtonVariantTypes.TERTIARY,
|
|
backgroundColor,
|
|
);
|
|
expect(result5).toStrictEqual(expected5);
|
|
|
|
// variant : TERTIARY without background
|
|
const expected6 = "rgba(255, 255, 255, 0.1)";
|
|
const result6 = getCustomHoverColor(theme, ButtonVariantTypes.TERTIARY);
|
|
expect(result6).toStrictEqual(expected6);
|
|
});
|
|
|
|
it("Check if the color is lightened with lightenColor utility", () => {
|
|
/**
|
|
* Colors with :
|
|
* 0% brightness = #000000,
|
|
* > 40% brightness = #696969
|
|
* > 50% brightness = #8a8a8a
|
|
* > 60% brightness = #b0b0b0
|
|
* > 70% brightness = #d6d4d4
|
|
*/
|
|
|
|
const actualColors = [
|
|
"#000000",
|
|
"#696969",
|
|
"#8a8a8a",
|
|
"#b0b0b0",
|
|
"#d6d4d4",
|
|
];
|
|
const lightColors = ["#ededed", "#ededed", "#ededed", "#ededed", "#eeeded"];
|
|
|
|
actualColors.forEach((color, idx) => {
|
|
expect(lightenColor(color)).toEqual(lightColors[idx]);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe(".sanitizeKey", () => {
|
|
it("returns sanitized value when passed a valid string", () => {
|
|
const inputAndExpectedOutput = [
|
|
["lowercase", "lowercase"],
|
|
["__abc__", "__abc__"],
|
|
["lower_snake_case", "lower_snake_case"],
|
|
["UPPER_SNAKE_CASE", "UPPER_SNAKE_CASE"],
|
|
["PascalCase", "PascalCase"],
|
|
["camelCase", "camelCase"],
|
|
["lower-kebab-case", "lower_kebab_case"],
|
|
["UPPER_KEBAB-CASE", "UPPER_KEBAB_CASE"],
|
|
["Sentencecase", "Sentencecase"],
|
|
["", "_"],
|
|
["with space", "with_space"],
|
|
["with multiple spaces", "with_multiple__spaces"],
|
|
["with%special)characters", "with_special_characters"],
|
|
["with%$multiple_spl.)characters", "with__multiple_spl__characters"],
|
|
["1startingWithNumber", "_1startingWithNumber"],
|
|
];
|
|
|
|
inputAndExpectedOutput.forEach(([input, expectedOutput]) => {
|
|
const result = sanitizeKey(input);
|
|
expect(result).toEqual(expectedOutput);
|
|
});
|
|
});
|
|
|
|
it("returns sanitized value when valid string with existing keys and reserved keys", () => {
|
|
const existingKeys = [
|
|
"__id",
|
|
"__restricted__",
|
|
"firstName1",
|
|
"_1age",
|
|
"gender",
|
|
"poll123",
|
|
"poll124",
|
|
"poll125",
|
|
"address_",
|
|
];
|
|
|
|
const inputAndExpectedOutput = [
|
|
["lowercase", "lowercase"],
|
|
["__abc__", "__abc__"],
|
|
["lower_snake_case", "lower_snake_case"],
|
|
["UPPER_SNAKE_CASE", "UPPER_SNAKE_CASE"],
|
|
["PascalCase", "PascalCase"],
|
|
["camelCase", "camelCase"],
|
|
["lower-kebab-case", "lower_kebab_case"],
|
|
["UPPER_KEBAB-CASE", "UPPER_KEBAB_CASE"],
|
|
["Sentencecase", "Sentencecase"],
|
|
["", "_"],
|
|
["with space", "with_space"],
|
|
["with multiple spaces", "with_multiple__spaces"],
|
|
["with%special)characters", "with_special_characters"],
|
|
["with%$multiple_spl.)characters", "with__multiple_spl__characters"],
|
|
["1startingWithNumber", "_1startingWithNumber"],
|
|
["1startingWithNumber", "_1startingWithNumber"],
|
|
["firstName", "firstName"],
|
|
["firstName1", "firstName2"],
|
|
["1age", "_1age1"],
|
|
["address&", "address_1"],
|
|
["%&id", "__id1"],
|
|
["%&restricted*(", "__restricted__1"],
|
|
["poll130", "poll130"],
|
|
["poll124", "poll126"],
|
|
["हिन्दि", "xn__j2bd4cyac6f"],
|
|
["😃", "xn__h28h"],
|
|
];
|
|
|
|
inputAndExpectedOutput.forEach(([input, expectedOutput]) => {
|
|
const result = sanitizeKey(input, {
|
|
existingKeys,
|
|
});
|
|
expect(result).toEqual(expectedOutput);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("Test widget utility functions", () => {
|
|
it("case: fontSizeUtility returns the font sizes based on variant", () => {
|
|
const expectedFontSize = "0.75rem";
|
|
|
|
expect(fontSizeUtility(TextSizes.PARAGRAPH2)).toEqual(expectedFontSize);
|
|
});
|
|
|
|
it("case: borderRadiusUtility returns the borderRadius based on borderRadius variant", () => {
|
|
const expectedBorderRadius = "0.375rem";
|
|
expect(borderRadiusUtility(ButtonBorderRadiusTypes.ROUNDED)).toEqual(
|
|
expectedBorderRadius,
|
|
);
|
|
});
|
|
|
|
it("case: replaceRgbaMigrationConstant returns the new boxShadow by replacing default boxShadowColor with new boxShadowColor", () => {
|
|
const boxShadow = "0px 0px 4px 3px rgba(0, 0, 0, 0.25)";
|
|
const boxShadowColor = "red";
|
|
const expectedBoxShadow = "0px 0px 4px 3px red";
|
|
expect(replaceRgbaMigrationConstant(boxShadow, boxShadowColor)).toEqual(
|
|
expectedBoxShadow,
|
|
);
|
|
});
|
|
|
|
it("case: boxShadowUtility returns the new boxShadow", () => {
|
|
const variants = [
|
|
"VARIANT1",
|
|
"VARIANT2",
|
|
"VARIANT3",
|
|
"VARIANT4",
|
|
"VARIANT5",
|
|
];
|
|
let newBoxShadowColor = rgbaMigrationConstantV56;
|
|
let expectedBoxShadows = [
|
|
`0px 0px 4px 3px ${newBoxShadowColor}`,
|
|
`3px 3px 4px ${newBoxShadowColor}`,
|
|
`0px 1px 3px ${newBoxShadowColor}`,
|
|
`2px 2px 0px ${newBoxShadowColor}`,
|
|
`-2px -2px 0px ${newBoxShadowColor}`,
|
|
];
|
|
|
|
// Check the boxShadow when the boxShadowColor is set to default;
|
|
variants.forEach((value: string, index: number) => {
|
|
expect(boxShadowUtility(value, newBoxShadowColor)).toEqual(
|
|
expectedBoxShadows[index],
|
|
);
|
|
});
|
|
|
|
// Check the boxShadow when the boxShadowColor is set to custom color;
|
|
newBoxShadowColor = "red";
|
|
expectedBoxShadows = [
|
|
`0px 0px 4px 3px ${newBoxShadowColor}`,
|
|
`3px 3px 4px ${newBoxShadowColor}`,
|
|
`0px 1px 3px ${newBoxShadowColor}`,
|
|
`2px 2px 0px ${newBoxShadowColor}`,
|
|
`-2px -2px 0px ${newBoxShadowColor}`,
|
|
];
|
|
variants.forEach((value: string, index: number) => {
|
|
expect(boxShadowUtility(value, newBoxShadowColor)).toEqual(
|
|
expectedBoxShadows[index],
|
|
);
|
|
});
|
|
});
|
|
|
|
it("case: boxShadowMigration returns correct boxShadow whenever boxShadow and boxShadowColor ar dynamic", () => {
|
|
/**
|
|
* Function usd inside table widget cell properties for Icon and menu button types.
|
|
* This function is used to run theming migration boxShadow and boxShadowColor has dynamic bindings
|
|
* Function runs for the following scenarios, when:
|
|
* 1. boxShadow: Static; boxShadowColor: Dynamic
|
|
* 2. boxShadow: Dynamic; boxShadowColor: Static
|
|
* 3. boxShadow: Dynamic; boxShadowColor: empty
|
|
* 4. boxShadow: Dynamic; boxShadowColor: dynamic
|
|
*/
|
|
|
|
// Case 1:
|
|
expect(
|
|
boxShadowMigration(
|
|
tableWidgetProps.dynamicBindingPathList as any,
|
|
"action",
|
|
"0px 0px 4px 3px rgba(0, 0, 0, 0.25)",
|
|
"red",
|
|
),
|
|
).toEqual("0px 0px 4px 3px red");
|
|
|
|
// Case 2 & 3:
|
|
// Make boxShadow dynamic
|
|
/**
|
|
* 1. Add the boxShadow to the DBPL
|
|
* 2. Remove boxShadowColor from the DBPL
|
|
* 3. Assign the action.boxShadowcolor as a static value.
|
|
* 4. Assign the action.boxShadowcolor as a empty value.
|
|
*/
|
|
tableWidgetProps.dynamicBindingPathList.push({
|
|
key: "primaryColumns.action.boxShadow",
|
|
});
|
|
// Remove boxShadowColor from dynamicBindingPathList
|
|
remove(
|
|
tableWidgetProps.dynamicBindingPathList,
|
|
(value: { key: string }) =>
|
|
value.key === "primaryColumns.action.boxShadowColor",
|
|
);
|
|
// Assign values to boxShadow and boxShadowColor
|
|
tableWidgetProps.primaryColumns.action.boxShadow = "VARIANT1";
|
|
tableWidgetProps.primaryColumns.action.boxShadowColor = "blue" as any;
|
|
let newBoxShadow = boxShadowMigration(
|
|
tableWidgetProps.dynamicBindingPathList as any,
|
|
"action",
|
|
tableWidgetProps.primaryColumns.action.boxShadow,
|
|
tableWidgetProps.primaryColumns.action.boxShadowColor,
|
|
);
|
|
expect(newBoxShadow).toEqual("0px 0px 4px 3px blue");
|
|
|
|
tableWidgetProps.primaryColumns.action.boxShadow = "VARIANT1";
|
|
tableWidgetProps.primaryColumns.action.boxShadowColor = "" as any; // Add empty boxShadowColor.
|
|
|
|
newBoxShadow = boxShadowMigration(
|
|
tableWidgetProps.dynamicBindingPathList as any,
|
|
"action",
|
|
tableWidgetProps.primaryColumns.action.boxShadow,
|
|
tableWidgetProps.primaryColumns.action.boxShadowColor,
|
|
);
|
|
expect(newBoxShadow).toEqual("0px 0px 4px 3px rgba(0, 0, 0, 0.25)");
|
|
|
|
// Case 4:
|
|
// Add boxShadow and boxShadowColor to the dynamicBindingPathList
|
|
tableWidgetProps.dynamicBindingPathList = [
|
|
...tableWidgetProps.dynamicBindingPathList,
|
|
{
|
|
key: "primaryColumns.action.boxShadow",
|
|
},
|
|
{
|
|
key: "primaryColumns.action.boxShadowColor",
|
|
},
|
|
];
|
|
|
|
// Assign values to boxShadow and boxShadowColor
|
|
tableWidgetProps.primaryColumns.action.boxShadow = "VARIANT1";
|
|
tableWidgetProps.primaryColumns.action.boxShadowColor = [
|
|
"orange",
|
|
"orange",
|
|
"orange",
|
|
];
|
|
newBoxShadow = boxShadowMigration(
|
|
tableWidgetProps.dynamicBindingPathList as any,
|
|
"action",
|
|
tableWidgetProps.primaryColumns.action.boxShadow,
|
|
tableWidgetProps.primaryColumns.action.boxShadowColor[0],
|
|
);
|
|
expect(newBoxShadow).toEqual("0px 0px 4px 3px orange");
|
|
|
|
tableWidgetProps.primaryColumns.action.boxShadow = "VARIANT1";
|
|
tableWidgetProps.primaryColumns.action.boxShadowColor = ["", "", ""] as any; // Add empty boxShadowColor when dynamic
|
|
|
|
// Add empty boxShadowColor.
|
|
newBoxShadow = boxShadowMigration(
|
|
tableWidgetProps.dynamicBindingPathList as any,
|
|
"action",
|
|
tableWidgetProps.primaryColumns.action.boxShadow,
|
|
tableWidgetProps.primaryColumns.action.boxShadowColor[0],
|
|
);
|
|
expect(newBoxShadow).toEqual("0px 0px 4px 3px rgba(0, 0, 0, 0.25)");
|
|
});
|
|
});
|
|
|
|
type composePropertyUpdateHookInputType = Array<
|
|
(
|
|
props: unknown,
|
|
propertyPath: string,
|
|
propertyValue: any,
|
|
) => PropertyHookUpdates[] | undefined
|
|
>;
|
|
describe("composePropertyUpdateHook", () => {
|
|
it("should test that it's returning a function", () => {
|
|
expect(typeof composePropertyUpdateHook([() => undefined])).toEqual(
|
|
"function",
|
|
);
|
|
});
|
|
|
|
it("should test that calling the function concats the returned values of input functions in the given order", () => {
|
|
const input = [() => [1], () => [2], () => [3], () => [4]];
|
|
|
|
const expected = [1, 2, 3, 4];
|
|
|
|
expect(
|
|
composePropertyUpdateHook(
|
|
(input as unknown) as composePropertyUpdateHookInputType,
|
|
)(null, "", null),
|
|
).toEqual(expected);
|
|
});
|
|
|
|
it("should test that calling the function concats the returned values of input functions in the given order and ignores undefined", () => {
|
|
const input = [() => [1], () => undefined, () => [3], () => [4]];
|
|
|
|
const expected = [1, 3, 4];
|
|
|
|
expect(
|
|
composePropertyUpdateHook(
|
|
(input as unknown) as composePropertyUpdateHookInputType,
|
|
)(null, "", null),
|
|
).toEqual(expected);
|
|
});
|
|
|
|
it("should test that calling the function without any function returns undefined", () => {
|
|
const input: any = [];
|
|
|
|
const expected = undefined;
|
|
|
|
expect(composePropertyUpdateHook(input)(null, "", null)).toEqual(expected);
|
|
});
|
|
});
|
|
|
|
const DUMMY_WIDGET: WidgetProps = {
|
|
bottomRow: 0,
|
|
isLoading: false,
|
|
leftColumn: 0,
|
|
parentColumnSpace: 0,
|
|
parentRowSpace: 0,
|
|
renderMode: RenderModes.CANVAS,
|
|
rightColumn: 0,
|
|
topRow: 0,
|
|
type: "SKELETON_WIDGET",
|
|
version: 2,
|
|
widgetId: "",
|
|
widgetName: "",
|
|
};
|
|
describe("Auto Height Utils", () => {
|
|
it("should return true if withLimits is true and widget has AUTO_HEIGHT_WITH_LIMITS", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "AUTO_HEIGHT_WITH_LIMITS",
|
|
};
|
|
|
|
const result = isAutoHeightEnabledForWidget(props, true);
|
|
expect(result).toBe(true);
|
|
});
|
|
it("should return false if withLimits is true and widget has AUTO_HEIGHT", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "AUTO_HEIGHT",
|
|
};
|
|
|
|
const result = isAutoHeightEnabledForWidget(props, true);
|
|
expect(result).toBe(false);
|
|
});
|
|
it("should return true if withLimits is false and widget has AUTO_HEIGHT", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "AUTO_HEIGHT",
|
|
};
|
|
|
|
const result = isAutoHeightEnabledForWidget(props, false);
|
|
expect(result).toBe(true);
|
|
});
|
|
|
|
it("should return false withLimits is false and widget has FIXED", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "FIXED",
|
|
};
|
|
|
|
const result = isAutoHeightEnabledForWidget(props, false);
|
|
expect(result).toBe(false);
|
|
});
|
|
it("should return false withLimits is true and widget has FIXED", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "FIXED",
|
|
};
|
|
|
|
const result = isAutoHeightEnabledForWidget(props, true);
|
|
expect(result).toBe(false);
|
|
});
|
|
it("should return 9000 if widget has AUTO_HEIGHT", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "AUTO_HEIGHT",
|
|
maxDynamicHeight: 20,
|
|
};
|
|
|
|
const result = getWidgetMaxAutoHeight(props);
|
|
expect(result).toBe(WidgetHeightLimits.MAX_HEIGHT_IN_ROWS);
|
|
});
|
|
it("should return 20 if widget has AUTO_HEIGHT_WITH_LIMITS", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "AUTO_HEIGHT_WITH_LIMITS",
|
|
maxDynamicHeight: 20,
|
|
};
|
|
|
|
const result = getWidgetMaxAutoHeight(props);
|
|
expect(result).toBe(20);
|
|
});
|
|
it("should return 9000 if widget has AUTO_HEIGHT_WITH_LIMITS and maxDynamicHeight is undefined", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "AUTO_HEIGHT_WITH_LIMITS",
|
|
maxDynamicHeight: undefined,
|
|
};
|
|
|
|
const result = getWidgetMaxAutoHeight(props);
|
|
expect(result).toBe(WidgetHeightLimits.MAX_HEIGHT_IN_ROWS);
|
|
});
|
|
|
|
it("should return undefined if widget is FIXED ", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "FIXED",
|
|
maxDynamicHeight: undefined,
|
|
};
|
|
|
|
const result = getWidgetMaxAutoHeight(props);
|
|
expect(result).toBeUndefined();
|
|
});
|
|
|
|
it("should return 4 if widget has AUTO_HEIGHT", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "AUTO_HEIGHT",
|
|
minDynamicHeight: 20,
|
|
};
|
|
|
|
const result = getWidgetMinAutoHeight(props);
|
|
expect(result).toBe(WidgetHeightLimits.MIN_HEIGHT_IN_ROWS);
|
|
});
|
|
it("should return 20 if widget has AUTO_HEIGHT_WITH_LIMITS", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "AUTO_HEIGHT_WITH_LIMITS",
|
|
minDynamicHeight: 20,
|
|
};
|
|
|
|
const result = getWidgetMinAutoHeight(props);
|
|
expect(result).toBe(20);
|
|
});
|
|
it("should return 4 if widget has AUTO_HEIGHT_WITH_LIMITS and minDynamicHeight is undefined", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "AUTO_HEIGHT_WITH_LIMITS",
|
|
minDynamicHeight: undefined,
|
|
};
|
|
|
|
const result = getWidgetMinAutoHeight(props);
|
|
expect(result).toBe(WidgetHeightLimits.MIN_HEIGHT_IN_ROWS);
|
|
});
|
|
|
|
it("should return undefined if widget is FIXED ", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "FIXED",
|
|
minDynamicHeight: undefined,
|
|
};
|
|
|
|
const result = getWidgetMinAutoHeight(props);
|
|
expect(result).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("Should Update Widget Height Automatically?", () => {
|
|
it("Multiple scenario tests", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "AUTO_HEIGHT_WITH_LIMITS",
|
|
minDynamicHeight: 19,
|
|
maxDynamicHeight: 40,
|
|
topRow: 20,
|
|
bottomRow: 40,
|
|
};
|
|
|
|
const inputs = [
|
|
600, // Is beyond max height of 40 rows,
|
|
560, // Is beyond max height of 40 rows
|
|
220, // Is within 20 and 40 rows limits
|
|
180, // Is below the min of 20 rows
|
|
200, // Is the same as current height
|
|
190, // Is exactly min value
|
|
400, // Is exactly max value
|
|
0, // Is below the min possible value
|
|
100, // Is below the min possible value
|
|
];
|
|
const expected = [
|
|
true, // because currentHeight is not close to maxDynamicHeight
|
|
true, // because currentheight is not close to maxDynamicHeight
|
|
true,
|
|
true, // because we need to go as low as possible (minDynamicHeight)
|
|
true,
|
|
true,
|
|
true,
|
|
true, // because we need to go as low as possible (minDynamicHeight)
|
|
true, // because we need to go as low as possible (minDynamicHeight)
|
|
];
|
|
|
|
inputs.forEach((input, index) => {
|
|
const result = shouldUpdateWidgetHeightAutomatically(input, props);
|
|
expect(result).toStrictEqual(expected[index]);
|
|
});
|
|
});
|
|
it("When height is below min rows, should update, no matter the expectations", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "AUTO_HEIGHT_WITH_LIMITS",
|
|
minDynamicHeight: 19,
|
|
maxDynamicHeight: 40,
|
|
topRow: 20,
|
|
bottomRow: 25,
|
|
};
|
|
|
|
const input = 0;
|
|
const expected = true;
|
|
|
|
const result = shouldUpdateWidgetHeightAutomatically(input, props);
|
|
expect(result).toStrictEqual(expected);
|
|
});
|
|
it("When height is above max rows, should update, no matter the expectations", () => {
|
|
const props = {
|
|
...DUMMY_WIDGET,
|
|
dynamicHeight: "AUTO_HEIGHT_WITH_LIMITS",
|
|
minDynamicHeight: 19,
|
|
maxDynamicHeight: 40,
|
|
topRow: 20,
|
|
bottomRow: 65,
|
|
};
|
|
|
|
const input = 0;
|
|
const expected = true;
|
|
|
|
const result = shouldUpdateWidgetHeightAutomatically(input, props);
|
|
expect(result).toStrictEqual(expected);
|
|
});
|
|
});
|