diff --git a/frontend/assets/images/icons/widgets/horizontalDivider.jsx b/frontend/assets/images/icons/widgets/horizontalDivider.jsx
new file mode 100644
index 0000000000..6f843ae57a
--- /dev/null
+++ b/frontend/assets/images/icons/widgets/horizontalDivider.jsx
@@ -0,0 +1,22 @@
+import React from 'react';
+
+const HorizontalDivider = ({ fill = '#D7DBDF', width = 24, className = '', viewBox = '0 0 49 48' }) => (
+
+);
+
+export default HorizontalDivider;
diff --git a/frontend/assets/images/icons/widgets/index.jsx b/frontend/assets/images/icons/widgets/index.jsx
index 5f1715689c..82ec948164 100644
--- a/frontend/assets/images/icons/widgets/index.jsx
+++ b/frontend/assets/images/icons/widgets/index.jsx
@@ -13,8 +13,6 @@ import Customcomponent from './customcomponent.jsx';
import Datepicker from './datepicker.jsx';
import DateTimePickerV2 from './datetimepickerV2.jsx';
import Daterangepicker from './daterangepicker.jsx';
-import Divider from './divider.jsx';
-import DividerHorizondal from './dividerhorizontal.jsx';
import Downstatistics from './downstatistics.jsx';
import Dropdown from './dropdown.jsx';
import Filepicker from './filepicker.jsx';
@@ -59,6 +57,7 @@ import Upstatistics from './upstatistics.jsx';
import Verticaldivider from './verticaldivider.jsx';
import TimePicker from './timepicker.jsx';
import DatepickerV2 from './datepickerv2.jsx';
+import HorizontalDivider from './horizontalDivider.jsx';
import PhoneInput from './phoneinput.jsx';
import EmailInput from './emailinput.jsx';
@@ -108,9 +107,7 @@ const WidgetIcon = (props) => {
case 'daterangepicker':
return ;
case 'horizontaldivider':
- return ;
- case 'divider-horizondal':
- return ;
+ return ;
case 'downstatistics':
return ;
case 'dropdown':
diff --git a/frontend/src/AppBuilder/AppCanvas/RenderWidget.jsx b/frontend/src/AppBuilder/AppCanvas/RenderWidget.jsx
index 7862db5676..f6d6419ac4 100644
--- a/frontend/src/AppBuilder/AppCanvas/RenderWidget.jsx
+++ b/frontend/src/AppBuilder/AppCanvas/RenderWidget.jsx
@@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next';
import ErrorBoundary from '@/_ui/ErrorBoundary';
import { BOX_PADDING } from './appCanvasConstants';
-const shouldAddBoxShadowAndVisibility = [
+const SHOULD_ADD_BOX_SHADOW_AND_VISIBILITY = [
'Table',
'TextInput',
'TextArea',
@@ -30,6 +30,8 @@ const shouldAddBoxShadowAndVisibility = [
'DaterangePicker',
'DatePickerV2',
'TimePicker',
+ 'Divider',
+ 'VerticalDivider',
'Link',
];
@@ -147,23 +149,22 @@ const RenderWidget = ({
placement={inCanvas ? 'auto' : 'top'}
delay={{ show: 500, hide: 0 }}
trigger={
- inCanvas && shouldAddBoxShadowAndVisibility.includes(component?.component)
+ inCanvas && SHOULD_ADD_BOX_SHADOW_AND_VISIBILITY.includes(component?.component)
? !resolvedProperties?.tooltip?.toString().trim()
? null
: ['hover', 'focus']
: !resolvedGeneralProperties?.tooltip?.toString().trim()
- ? null
- : ['hover', 'focus']
+ ? null
+ : ['hover', 'focus']
}
overlay={(props) =>
renderTooltip({
props,
text: inCanvas
- ? `${
- shouldAddBoxShadowAndVisibility.includes(component?.component)
- ? resolvedProperties?.tooltip
- : resolvedGeneralProperties?.tooltip
- }`
+ ? `${SHOULD_ADD_BOX_SHADOW_AND_VISIBILITY.includes(component?.component)
+ ? resolvedProperties?.tooltip
+ : resolvedGeneralProperties?.tooltip
+ }`
: `${t(`widget.${component?.name}.description`, component?.description)}`,
})
}
diff --git a/frontend/src/AppBuilder/RightSideBar/Inspector/Components/DefaultComponent.jsx b/frontend/src/AppBuilder/RightSideBar/Inspector/Components/DefaultComponent.jsx
index c7104edb40..346d0bfc17 100644
--- a/frontend/src/AppBuilder/RightSideBar/Inspector/Components/DefaultComponent.jsx
+++ b/frontend/src/AppBuilder/RightSideBar/Inspector/Components/DefaultComponent.jsx
@@ -27,6 +27,8 @@ const SHOW_ADDITIONAL_ACTIONS = [
'Button',
'RichTextEditor',
'Image',
+ 'Divider',
+ 'VerticalDivider',
'ModalV2',
'Link',
];
@@ -41,6 +43,8 @@ const PROPERTIES_VS_ACCORDION_TITLE = {
Button: 'Data',
Image: 'Data',
Container: 'Data',
+ Divider: 'Data',
+ VerticalDivider: 'Data',
ModalV2: 'Data',
Link: 'Data',
};
@@ -140,6 +144,8 @@ export const baseComponentProperties = (
'DropdownV2',
'MultiselectV2',
'Image',
+ 'Divider',
+ 'VerticalDivider',
'Link',
],
Layout: [],
@@ -280,7 +286,6 @@ export const baseComponentProperties = (
>
),
});
-
return items.filter(
(item) => !(item.title in accordionFilters && accordionFilters[item.title].includes(componentMeta.component))
);
diff --git a/frontend/src/AppBuilder/RightSideBar/Inspector/Inspector.jsx b/frontend/src/AppBuilder/RightSideBar/Inspector/Inspector.jsx
index 9e227b1e05..e101069fdb 100644
--- a/frontend/src/AppBuilder/RightSideBar/Inspector/Inspector.jsx
+++ b/frontend/src/AppBuilder/RightSideBar/Inspector/Inspector.jsx
@@ -86,6 +86,8 @@ const NEW_REVAMPED_COMPONENTS = [
'Icon',
'Image',
'Container',
+ 'Divider',
+ 'VerticalDivider',
'ModalV2',
'Link',
];
diff --git a/frontend/src/AppBuilder/WidgetManager/widgets/divider.js b/frontend/src/AppBuilder/WidgetManager/widgets/divider.js
index 3905c7583d..33b64d9f56 100644
--- a/frontend/src/AppBuilder/WidgetManager/widgets/divider.js
+++ b/frontend/src/AppBuilder/WidgetManager/widgets/divider.js
@@ -1,6 +1,6 @@
export const dividerConfig = {
- name: 'Divider',
- displayName: 'Divider',
+ name: 'HorizontalDivider',
+ displayName: 'Horizontal divider',
description: 'Separator between components',
component: 'Divider',
defaultSize: {
@@ -11,15 +11,12 @@ export const dividerConfig = {
showOnDesktop: { type: 'toggle', displayName: 'Show on desktop' },
showOnMobile: { type: 'toggle', displayName: 'Show on mobile' },
},
- properties: {},
- events: {},
- styles: {
- dividerColor: {
- type: 'colorSwatches',
- displayName: 'Divider color',
+ properties: {
+ label: {
+ type: 'code',
+ displayName: 'Label',
validation: {
schema: { type: 'string' },
- defaultValue: '#000000',
},
},
visibility: {
@@ -29,6 +26,109 @@ export const dividerConfig = {
schema: { type: 'boolean' },
defaultValue: true,
},
+ section: 'additionalActions',
+ },
+ tooltip: {
+ type: 'code',
+ displayName: 'Tooltip',
+ validation: { schema: { type: 'string' }, defaultValue: 'Tooltip text' },
+ section: 'additionalActions',
+ placeholder: 'Enter tooltip text',
+ },
+ },
+ events: {},
+ styles: {
+ dividerColor: {
+ type: 'colorSwatches',
+ displayName: 'Divider color',
+ validation: {
+ schema: { type: 'string' },
+ },
+ },
+ visibility: {
+ type: 'toggle',
+ displayName: 'Visibility',
+ validation: {
+ schema: { type: 'boolean' },
+ defaultValue: true,
+ },
+ section: 'additionalActions',
+ },
+ tooltip: {
+ type: 'code',
+ displayName: 'Tooltip',
+ validation: { schema: { type: 'string' }, defaultValue: 'Tooltip text' },
+ section: 'additionalActions',
+ placeholder: 'Enter tooltip text',
+ },
+ },
+ events: {},
+ styles: {
+ dividerColor: {
+ type: 'color',
+ displayName: 'Divider color',
+ validation: {
+ schema: { type: 'string' },
+ defaultValue: '#000000',
+ },
+ accordian: 'Divider',
+ },
+ dividerStyle: {
+ type: 'switch',
+ displayName: 'Style',
+ validation: {
+ schema: { type: 'string' },
+ },
+ options: [
+ { displayName: 'Solid', value: 'solid' },
+ { displayName: 'Dashed', value: 'dashed' },
+ ],
+ accordian: 'Divider',
+ },
+ labelAlignment: {
+ type: 'switch',
+ displayName: 'Label alignment',
+ validation: { schema: { type: 'string' }, defaultValue: 'left' },
+ showLabel: true,
+ isIcon: true,
+ options: [
+ { displayName: 'alignleftinspector', value: 'left', iconName: 'alignleftinspector' },
+ { displayName: 'alignhorizontalcenter', value: 'center', iconName: 'alignhorizontalcenter' },
+ { displayName: 'alignrightinspector', value: 'right', iconName: 'alignrightinspector' },
+ ],
+ accordian: 'Divider',
+ isFxNotRequired: true,
+ },
+ labelColor: {
+ type: 'color',
+ displayName: 'Label Color',
+ validation: {
+ schema: { type: 'string' },
+ },
+ accordian: 'Divider',
+ },
+ boxShadow: {
+ type: 'boxShadow',
+ displayName: 'Box Shadow',
+ validation: {
+ schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
+ defaultValue: '0px 0px 0px 0px #00000040',
+ },
+ accordian: 'Divider',
+ },
+ padding: {
+ type: 'switch',
+ displayName: 'Padding',
+ validation: {
+ schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
+ defaultValue: 'default',
+ },
+ isFxNotRequired: true,
+ options: [
+ { displayName: 'Default', value: 'default' },
+ { displayName: 'None', value: 'none' },
+ ],
+ accordian: 'container',
},
},
exposedVariables: {
@@ -39,11 +139,19 @@ export const dividerConfig = {
showOnDesktop: { value: '{{true}}' },
showOnMobile: { value: '{{false}}' },
},
- properties: {},
+ properties: {
+ label: { value: '' },
+ visibility: { value: '{{true}}' },
+ tooltip: { value: '' },
+ },
events: [],
styles: {
- visibility: { value: '{{true}}' },
- dividerColor: { value: '#000000' },
+ dividerColor: { value: '#CCD1D5' },
+ labelAlignment: { value: 'center' },
+ dividerStyle: { value: 'solid' },
+ labelColor: { value: '#6A727C' },
+ padding: { value: 'default' },
+ boxShadow: { value: '0px 0px 0px 0px #00000040' },
},
},
};
diff --git a/frontend/src/AppBuilder/WidgetManager/widgets/verticalDivider.js b/frontend/src/AppBuilder/WidgetManager/widgets/verticalDivider.js
index e43b81adf7..df426c7b5f 100644
--- a/frontend/src/AppBuilder/WidgetManager/widgets/verticalDivider.js
+++ b/frontend/src/AppBuilder/WidgetManager/widgets/verticalDivider.js
@@ -1,17 +1,34 @@
export const verticalDividerConfig = {
name: 'VerticalDivider',
- displayName: 'Vertical Divider',
+ displayName: 'Vertical divider',
description: 'Vertical line separator',
component: 'VerticalDivider',
defaultSize: {
- width: 2,
+ width: 1,
height: 100,
},
others: {
showOnDesktop: { type: 'toggle', displayName: 'Show on desktop' },
showOnMobile: { type: 'toggle', displayName: 'Show on mobile' },
},
- properties: {},
+ properties: {
+ visibility: {
+ type: 'toggle',
+ displayName: 'Visibility',
+ validation: {
+ schema: { type: 'boolean' },
+ defaultValue: true,
+ },
+ section: 'additionalActions',
+ },
+ tooltip: {
+ type: 'code',
+ displayName: 'Tooltip',
+ validation: { schema: { type: 'string' }, defaultValue: 'Tooltip text' },
+ section: 'additionalActions',
+ placeholder: 'Enter tooltip text',
+ },
+ },
events: {},
styles: {
dividerColor: {
@@ -21,14 +38,42 @@ export const verticalDividerConfig = {
schema: { type: 'string' },
defaultValue: '#000000',
},
+ accordian: 'Divider',
},
- visibility: {
- type: 'toggle',
- displayName: 'Visibility',
+ dividerStyle: {
+ type: 'switch',
+ displayName: 'Style',
validation: {
- schema: { type: 'boolean' },
- defaultValue: true,
+ schema: { type: 'string' },
},
+ options: [
+ { displayName: 'Solid', value: 'solid' },
+ { displayName: 'Dashed', value: 'dashed' },
+ ],
+ accordian: 'Divider',
+ },
+ boxShadow: {
+ type: 'boxShadow',
+ displayName: 'Box Shadow',
+ validation: {
+ schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
+ defaultValue: '0px 0px 0px 0px #00000040',
+ },
+ accordian: 'Divider',
+ },
+ padding: {
+ type: 'switch',
+ displayName: 'Padding',
+ validation: {
+ schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
+ defaultValue: 'default',
+ },
+ isFxNotRequired: true,
+ options: [
+ { displayName: 'Default', value: 'default' },
+ { displayName: 'None', value: 'none' },
+ ],
+ accordian: 'container',
},
},
exposedVariables: {
@@ -39,11 +84,16 @@ export const verticalDividerConfig = {
showOnDesktop: { value: '{{true}}' },
showOnMobile: { value: '{{false}}' },
},
- properties: {},
+ properties: {
+ visibility: { value: '{{true}}' },
+ tooltip: { value: '' },
+ },
events: [],
styles: {
- visibility: { value: '{{true}}' },
- dividerColor: { value: '#000000' },
+ dividerColor: { value: '#CCD1D5' },
+ dividerStyle: { value: 'solid' },
+ padding: { value: 'default' },
+ boxShadow: { value: '0px 0px 0px 0px #00000040' },
},
},
};
diff --git a/frontend/src/AppBuilder/_helpers/editorHelpers.js b/frontend/src/AppBuilder/_helpers/editorHelpers.js
index 545cc408a3..183c5c1cec 100644
--- a/frontend/src/AppBuilder/_helpers/editorHelpers.js
+++ b/frontend/src/AppBuilder/_helpers/editorHelpers.js
@@ -50,7 +50,7 @@ import { SvgImage } from '@/Editor/Components/SvgImage';
import { Html } from '@/Editor/Components/Html';
import { ButtonGroup } from '@/Editor/Components/ButtonGroup';
import { CustomComponent } from '@/Editor/Components/CustomComponent/CustomComponent';
-import { VerticalDivider } from '@/Editor/Components/verticalDivider';
+import { VerticalDivider } from '@/Editor/Components/VerticalDivider';
import { ColorPicker } from '@/Editor/Components/ColorPicker';
import { KanbanBoard } from '@/Editor/Components/KanbanBoard/KanbanBoard';
// import { Kanban } from '@/Editor/Components/Kanban/Kanban';
diff --git a/frontend/src/Editor/Components/Divider.jsx b/frontend/src/Editor/Components/Divider.jsx
index 5935181bf7..349c6f0ddc 100644
--- a/frontend/src/Editor/Components/Divider.jsx
+++ b/frontend/src/Editor/Components/Divider.jsx
@@ -1,20 +1,99 @@
import React from 'react';
-export const Divider = function Divider({ styles, dataCy, height, width, darkMode }) {
- const { visibility, dividerColor, boxShadow } = styles;
+const DASH_WIDTH = 4;
+const DASH_GAP = 4;
+export const Divider = function Divider({ dataCy, height, width, darkMode, styles, properties }) {
+ const { labelAlignment, labelColor, dividerColor, boxShadow, dividerStyle, padding } = styles;
+ const { label, visibility } = properties;
const color =
dividerColor === '' || ['#000', '#000000'].includes(dividerColor) ? (darkMode ? '#fff' : '#000') : dividerColor;
+
+ const dividerLineStyle = {
+ width: '100%',
+ padding: '0rem',
+ boxShadow,
+ ...(dividerStyle === 'dashed'
+ ? {
+ backgroundImage: `linear-gradient(to right, ${color} ${DASH_WIDTH}px, transparent ${DASH_GAP}px)`,
+ backgroundSize: `${DASH_WIDTH + DASH_GAP}px 1px`,
+ backgroundRepeat: 'repeat-x',
+ backgroundColor: 'transparent',
+ borderTop: 'none',
+ height: '1px',
+ }
+ : {
+ height: '1px',
+ backgroundColor: color,
+ borderTop: 'none',
+ }),
+ };
+
+ const labelStyles = {
+ color: labelColor,
+ boxShadow,
+ fontSize: '11px',
+ fontWeight: '500',
+ lineHeight: '16px',
+ };
+
+ // If no label, render the original divider
+ if (!label) {
+ return (
+
+ );
+ }
+
+ // With label - handle different positions
return (
-
+ {labelAlignment === 'left' && (
+ <>
+
{label}
+
+ >
+ )}
+
+ {labelAlignment === 'center' && (
+
+ )}
+
+ {labelAlignment === 'right' && (
+ <>
+
+
{label}
+ >
+ )}
);
};
diff --git a/frontend/src/Editor/Components/VerticalDivider.jsx b/frontend/src/Editor/Components/VerticalDivider.jsx
new file mode 100644
index 0000000000..76042c8908
--- /dev/null
+++ b/frontend/src/Editor/Components/VerticalDivider.jsx
@@ -0,0 +1,38 @@
+import React from 'react';
+const DASH_WIDTH = 4;
+const DASH_GAP = 4;
+
+export const VerticalDivider = function Divider({ styles, height, width, dataCy, darkMode, properties }) {
+ const { dividerColor, boxShadow, dividerStyle } = styles;
+ const color =
+ dividerColor === '' || ['#000', '#000000'].includes(dividerColor) ? (darkMode ? '#fff' : '#000') : dividerColor;
+
+ return (
+
+ );
+};
diff --git a/frontend/src/Editor/Components/verticalDivider.jsx b/frontend/src/Editor/Components/verticalDivider.jsx
deleted file mode 100644
index ba6a38748c..0000000000
--- a/frontend/src/Editor/Components/verticalDivider.jsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from 'react';
-
-export const VerticalDivider = function Divider({ styles, height, width, dataCy, darkMode }) {
- const { visibility, dividerColor, boxShadow } = styles;
- const color =
- dividerColor === '' || ['#000', '#000000'].includes(dividerColor) ? (darkMode ? '#fff' : '#000') : dividerColor;
-
- return (
-
- );
-};
diff --git a/frontend/src/Editor/WidgetManager/configs/divider.js b/frontend/src/Editor/WidgetManager/configs/divider.js
index 27ce6edf8e..82bb38da6f 100644
--- a/frontend/src/Editor/WidgetManager/configs/divider.js
+++ b/frontend/src/Editor/WidgetManager/configs/divider.js
@@ -1,5 +1,5 @@
export const dividerConfig = {
- name: 'horizontalDivider',
+ name: 'HorizontalDivider',
displayName: 'Horizontal Divider',
description: 'Separator between components',
component: 'Divider',
@@ -11,15 +11,12 @@ export const dividerConfig = {
showOnDesktop: { type: 'toggle', displayName: 'Show on desktop' },
showOnMobile: { type: 'toggle', displayName: 'Show on mobile' },
},
- properties: {},
- events: {},
- styles: {
- dividerColor: {
- type: 'color',
- displayName: 'Divider color',
+ properties: {
+ label: {
+ type: 'code',
+ displayName: 'Label',
validation: {
schema: { type: 'string' },
- defaultValue: '#000000',
},
},
visibility: {
@@ -29,6 +26,83 @@ export const dividerConfig = {
schema: { type: 'boolean' },
defaultValue: true,
},
+ section: 'additionalActions',
+ },
+ tooltip: {
+ type: 'code',
+ displayName: 'Tooltip',
+ validation: { schema: { type: 'string' }, defaultValue: 'Tooltip text' },
+ section: 'additionalActions',
+ placeholder: 'Enter tooltip text',
+ },
+ },
+ events: {},
+ styles: {
+ dividerColor: {
+ type: 'color',
+ displayName: 'Divider color',
+ validation: {
+ schema: { type: 'string' },
+ defaultValue: '#000000',
+ },
+ accordian: 'Divider',
+ },
+ dividerStyle: {
+ type: 'switch',
+ displayName: 'Style',
+ validation: {
+ schema: { type: 'string' },
+ },
+ options: [
+ { displayName: 'Solid', value: 'solid' },
+ { displayName: 'Dashed', value: 'dashed' },
+ ],
+ accordian: 'Divider',
+ },
+ labelAlignment: {
+ type: 'switch',
+ displayName: 'Label alignment',
+ validation: { schema: { type: 'string' }, defaultValue: 'left' },
+ showLabel: true,
+ isIcon: true,
+ options: [
+ { displayName: 'alignleftinspector', value: 'left', iconName: 'alignleftinspector' },
+ { displayName: 'alignhorizontalcenter', value: 'center', iconName: 'alignhorizontalcenter' },
+ { displayName: 'alignrightinspector', value: 'right', iconName: 'alignrightinspector' },
+ ],
+ accordian: 'Divider',
+ isFxNotRequired: true,
+ },
+ labelColor: {
+ type: 'color',
+ displayName: 'Label Color',
+ validation: {
+ schema: { type: 'string' },
+ },
+ accordian: 'Divider',
+ },
+ boxShadow: {
+ type: 'boxShadow',
+ displayName: 'Box Shadow',
+ validation: {
+ schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
+ defaultValue: '0px 0px 0px 0px #00000040',
+ },
+ accordian: 'Divider',
+ },
+ padding: {
+ type: 'switch',
+ displayName: 'Padding',
+ validation: {
+ schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
+ defaultValue: 'default',
+ },
+ isFxNotRequired: true,
+ options: [
+ { displayName: 'Default', value: 'default' },
+ { displayName: 'None', value: 'none' },
+ ],
+ accordian: 'container',
},
},
exposedVariables: {
@@ -39,11 +113,19 @@ export const dividerConfig = {
showOnDesktop: { value: '{{true}}' },
showOnMobile: { value: '{{false}}' },
},
- properties: {},
+ properties: {
+ label: { value: '' },
+ visibility: { value: '{{true}}' },
+ tooltip: { value: '' },
+ },
events: [],
styles: {
- visibility: { value: '{{true}}' },
- dividerColor: { value: '#000000' },
+ dividerColor: { value: '#CCD1D5' },
+ labelAlignment: { value: 'center' },
+ dividerStyle: { value: 'solid' },
+ labelColor: { value: '#6A727C' },
+ padding: { value: 'default' },
+ boxShadow: { value: '0px 0px 0px 0px #00000040' },
},
},
};
diff --git a/frontend/src/Editor/WidgetManager/configs/verticalDivider.js b/frontend/src/Editor/WidgetManager/configs/verticalDivider.js
index 443526c3b8..34d9029e3a 100644
--- a/frontend/src/Editor/WidgetManager/configs/verticalDivider.js
+++ b/frontend/src/Editor/WidgetManager/configs/verticalDivider.js
@@ -1,17 +1,34 @@
export const verticalDividerConfig = {
name: 'VerticalDivider',
- displayName: 'Vertical Divider',
+ displayName: 'Vertical divider',
description: 'Vertical line separator',
component: 'VerticalDivider',
defaultSize: {
- width: 2,
+ width: 1,
height: 100,
},
others: {
showOnDesktop: { type: 'toggle', displayName: 'Show on desktop' },
showOnMobile: { type: 'toggle', displayName: 'Show on mobile' },
},
- properties: {},
+ properties: {
+ visibility: {
+ type: 'toggle',
+ displayName: 'Visibility',
+ validation: {
+ schema: { type: 'boolean' },
+ defaultValue: true,
+ },
+ section: 'additionalActions',
+ },
+ tooltip: {
+ type: 'code',
+ displayName: 'Tooltip',
+ validation: { schema: { type: 'string' }, defaultValue: 'Tooltip text' },
+ section: 'additionalActions',
+ placeholder: 'Enter tooltip text',
+ },
+ },
events: {},
styles: {
dividerColor: {
@@ -21,14 +38,42 @@ export const verticalDividerConfig = {
schema: { type: 'string' },
defaultValue: '#000000',
},
+ accordian: 'Divider',
},
- visibility: {
- type: 'toggle',
- displayName: 'Visibility',
+ dividerStyle: {
+ type: 'switch',
+ displayName: 'Style',
validation: {
- schema: { type: 'boolean' },
- defaultValue: true,
+ schema: { type: 'string' },
},
+ options: [
+ { displayName: 'Solid', value: 'solid' },
+ { displayName: 'Dashed', value: 'dashed' },
+ ],
+ accordian: 'Divider',
+ },
+ boxShadow: {
+ type: 'boxShadow',
+ displayName: 'Box Shadow',
+ validation: {
+ schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
+ defaultValue: '0px 0px 0px 0px #00000040',
+ },
+ accordian: 'Divider',
+ },
+ padding: {
+ type: 'switch',
+ displayName: 'Padding',
+ validation: {
+ schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
+ defaultValue: 'default',
+ },
+ isFxNotRequired: true,
+ options: [
+ { displayName: 'Default', value: 'default' },
+ { displayName: 'None', value: 'none' },
+ ],
+ accordian: 'container',
},
},
exposedVariables: {
@@ -39,11 +84,16 @@ export const verticalDividerConfig = {
showOnDesktop: { value: '{{true}}' },
showOnMobile: { value: '{{false}}' },
},
- properties: {},
+ properties: {
+ visibility: { value: '{{true}}' },
+ tooltip: { value: '' },
+ },
events: [],
styles: {
- visibility: { value: '{{true}}' },
- dividerColor: { value: '#000000' },
+ dividerColor: { value: '#CCD1D5' },
+ dividerStyle: { value: 'solid' },
+ padding: { value: 'default' },
+ boxShadow: { value: '0px 0px 0px 0px #00000040' },
},
},
};
diff --git a/frontend/src/_helpers/editorHelpers.js b/frontend/src/_helpers/editorHelpers.js
index 35335477d0..c3c18a6587 100644
--- a/frontend/src/_helpers/editorHelpers.js
+++ b/frontend/src/_helpers/editorHelpers.js
@@ -42,7 +42,7 @@ import { SvgImage } from '@/Editor/Components/SvgImage';
import { Html } from '@/Editor/Components/Html';
import { ButtonGroup } from '@/Editor/Components/ButtonGroup';
import { CustomComponent } from '@/Editor/Components/CustomComponent/CustomComponent';
-import { VerticalDivider } from '@/Editor/Components/verticalDivider';
+import { VerticalDivider } from '@/Editor/Components/VerticalDivider';
import { ColorPicker } from '@/Editor/Components/ColorPicker';
import { KanbanBoard } from '@/Editor/Components/KanbanBoard/KanbanBoard';
import { Kanban } from '@/Editor/Components/Kanban/Kanban';
diff --git a/frontend/src/_ui/Icon/solidIcons/AlignHorizontalCenter.jsx b/frontend/src/_ui/Icon/solidIcons/AlignHorizontalCenter.jsx
new file mode 100644
index 0000000000..6b7b2f39ab
--- /dev/null
+++ b/frontend/src/_ui/Icon/solidIcons/AlignHorizontalCenter.jsx
@@ -0,0 +1,16 @@
+import React from 'react';
+
+const AlignHorizontalCenter = ({ fill = '', width = '25', className = '', viewBox = '0 0 25 25' }) => {
+ return (
+
+ );
+};
+
+export default AlignHorizontalCenter;
diff --git a/frontend/src/_ui/Icon/solidIcons/index.js b/frontend/src/_ui/Icon/solidIcons/index.js
index 02ef072f4a..a64674b0bb 100644
--- a/frontend/src/_ui/Icon/solidIcons/index.js
+++ b/frontend/src/_ui/Icon/solidIcons/index.js
@@ -171,6 +171,7 @@ import WorkspaceConstants from './WorkspaceConstants.jsx';
import ArrowBackDown from './ArrowBackDown.jsx';
import AlignRightinspector from './AlignRightinspector.jsx';
import AlignLeftinspector from './AlignLeftinspector.jsx';
+import AlignHorizontalCenter from './AlignHorizontalCenter.jsx';
import AlignVerticallyTop from './AlignVerticallyTop.jsx';
import AlignVerticallyBottom from './AlignVerticallyBottom.jsx';
import AlignVerticallyCenter from './AlignVerticallyCenter.jsx';
@@ -242,9 +243,11 @@ const Icon = (props) => {
case 'addrectangle':
return ;
case 'alignleftinspector':
- return ;
- case 'alignrightinspector':
return ;
+ case 'alignrightinspector':
+ return ;
+ case 'alignhorizontalcenter':
+ return ;
case 'alignverticallytop':
return ;
case 'alignverticallybottom':
diff --git a/server/data-migrations/1743053824028-MoveVisibilityDisabledStatesDividerLink.ts b/server/data-migrations/1743053824028-MoveVisibilityDisabledStatesDividerLink.ts
new file mode 100644
index 0000000000..21ff07dc0c
--- /dev/null
+++ b/server/data-migrations/1743053824028-MoveVisibilityDisabledStatesDividerLink.ts
@@ -0,0 +1,64 @@
+import { Component } from '@entities/component.entity';
+import { processDataInBatches } from '@helpers/migration.helper';
+import { EntityManager, MigrationInterface, QueryRunner } from 'typeorm';
+
+export class MoveVisibilityDisabledStatesDividerLink1743053824028 implements MigrationInterface {
+
+ public async up(queryRunner: QueryRunner): Promise {
+ const componentTypes = ['Divider', 'VerticalDivider', 'Link'];
+ const batchSize = 100;
+ const entityManager = queryRunner.manager;
+
+ for (const componentType of componentTypes) {
+ await processDataInBatches(
+ entityManager,
+ async (entityManager: EntityManager) => {
+ return await entityManager.find(Component, {
+ where: { type: componentType },
+ order: { createdAt: 'ASC' },
+ });
+ },
+ async (entityManager: EntityManager, components: Component[]) => {
+ await this.processUpdates(entityManager, components);
+ },
+ batchSize
+ );
+ }
+ }
+
+ private async processUpdates(entityManager, components) {
+ for (const component of components) {
+ const properties = component.properties;
+ const styles = component.styles;
+ const general = component.general;
+ const generalStyles = component.generalStyles;
+ const validation = component.validation;
+
+ if (styles.visibility) {
+ properties.visibility = styles.visibility;
+ delete styles.visibility;
+ }
+
+ if (general?.tooltip) {
+ properties.tooltip = general?.tooltip;
+ delete general?.tooltip;
+ }
+
+ if (generalStyles?.boxShadow) {
+ styles.boxShadow = generalStyles?.boxShadow;
+ delete generalStyles?.boxShadow;
+ }
+
+ await entityManager.update(Component, component.id, {
+ properties,
+ styles,
+ general,
+ generalStyles,
+ validation,
+ });
+ }
+ }
+ public async down(queryRunner: QueryRunner): Promise {
+ }
+
+}
diff --git a/server/src/modules/apps/services/app-import-export.service.ts b/server/src/modules/apps/services/app-import-export.service.ts
index abc2abce3e..6cd6b3ce8f 100644
--- a/server/src/modules/apps/services/app-import-export.service.ts
+++ b/server/src/modules/apps/services/app-import-export.service.ts
@@ -51,7 +51,7 @@ type DefaultDataSourceName =
| 'tooljetdbdefault'
| 'workflowsdefault';
-type NewRevampedComponent = 'Text' | 'TextInput' | 'PasswordInput' | 'NumberInput' | 'Table' | 'Button' | 'Checkbox';
+type NewRevampedComponent = 'Text' | 'TextInput' | 'PasswordInput' | 'NumberInput' | 'Table' | 'Button' | 'Checkbox' | 'Divider' | 'VerticalDivider' | 'Link';
const DefaultDataSourceNames: DefaultDataSourceName[] = [
'restapidefault',
@@ -69,6 +69,9 @@ const NewRevampedComponents: NewRevampedComponent[] = [
'Table',
'Checkbox',
'Button',
+ 'Divider',
+ 'VerticalDivider',
+ 'Link',
];
@Injectable()
@@ -79,7 +82,7 @@ export class AppImportExportService {
protected appEnvironmentUtilService: AppEnvironmentUtilService,
protected readonly entityManager: EntityManager,
protected componentsService: ComponentsService
- ) {}
+ ) { }
async export(user: User, id: string, searchParams: any = {}): Promise<{ appV2: App }> {
// https://github.com/typeorm/typeorm/issues/3857
@@ -181,13 +184,13 @@ export class AppImportExportService {
const components =
pages.length > 0
? await manager
- .createQueryBuilder(Component, 'components')
- .leftJoinAndSelect('components.layouts', 'layouts')
- .where('components.pageId IN(:...pageId)', {
- pageId: pages.map((v) => v.id),
- })
- .orderBy('components.created_at', 'ASC')
- .getMany()
+ .createQueryBuilder(Component, 'components')
+ .leftJoinAndSelect('components.layouts', 'layouts')
+ .where('components.pageId IN(:...pageId)', {
+ pageId: pages.map((v) => v.id),
+ })
+ .orderBy('components.created_at', 'ASC')
+ .getMany()
: [];
const events = await manager
@@ -1056,10 +1059,10 @@ export class AppImportExportService {
const options =
importingDataSource.kind === 'tooljetdb'
? this.replaceTooljetDbTableIds(
- importingQuery.options,
- externalResourceMappings['tooljet_database'],
- organizationId
- )
+ importingQuery.options,
+ externalResourceMappings['tooljet_database'],
+ organizationId
+ )
: importingQuery.options;
const newQuery = manager.create(DataQuery, {
@@ -1624,10 +1627,10 @@ export class AppImportExportService {
options:
dataSourceId == defaultDataSourceIds['tooljetdb']
? this.replaceTooljetDbTableIds(
- query.options,
- externalResourceMappings['tooljet_database'],
- user.organizationId
- )
+ query.options,
+ externalResourceMappings['tooljet_database'],
+ user.organizationId
+ )
: query.options,
});
await manager.save(newQuery);
diff --git a/server/src/modules/apps/services/widget-config/divider.js b/server/src/modules/apps/services/widget-config/divider.js
index 3905c7583d..1c173fd54d 100644
--- a/server/src/modules/apps/services/widget-config/divider.js
+++ b/server/src/modules/apps/services/widget-config/divider.js
@@ -1,6 +1,6 @@
export const dividerConfig = {
- name: 'Divider',
- displayName: 'Divider',
+ name: 'HorizontalDivider',
+ displayName: 'Horizontal Divider',
description: 'Separator between components',
component: 'Divider',
defaultSize: {
@@ -11,15 +11,12 @@ export const dividerConfig = {
showOnDesktop: { type: 'toggle', displayName: 'Show on desktop' },
showOnMobile: { type: 'toggle', displayName: 'Show on mobile' },
},
- properties: {},
- events: {},
- styles: {
- dividerColor: {
- type: 'colorSwatches',
- displayName: 'Divider color',
+ properties: {
+ label: {
+ type: 'code',
+ displayName: 'Label',
validation: {
schema: { type: 'string' },
- defaultValue: '#000000',
},
},
visibility: {
@@ -29,6 +26,109 @@ export const dividerConfig = {
schema: { type: 'boolean' },
defaultValue: true,
},
+ section: 'additionalActions',
+ },
+ tooltip: {
+ type: 'code',
+ displayName: 'Tooltip',
+ validation: { schema: { type: 'string' }, defaultValue: 'Tooltip text' },
+ section: 'additionalActions',
+ placeholder: 'Enter tooltip text',
+ },
+ },
+ events: {},
+ styles: {
+ dividerColor: {
+ type: 'colorSwatches',
+ displayName: 'Divider color',
+ validation: {
+ schema: { type: 'string' },
+ },
+ },
+ visibility: {
+ type: 'toggle',
+ displayName: 'Visibility',
+ validation: {
+ schema: { type: 'boolean' },
+ defaultValue: true,
+ },
+ section: 'additionalActions',
+ },
+ tooltip: {
+ type: 'code',
+ displayName: 'Tooltip',
+ validation: { schema: { type: 'string' }, defaultValue: 'Tooltip text' },
+ section: 'additionalActions',
+ placeholder: 'Enter tooltip text',
+ },
+ },
+ events: {},
+ styles: {
+ dividerColor: {
+ type: 'color',
+ displayName: 'Divider color',
+ validation: {
+ schema: { type: 'string' },
+ defaultValue: '#000000',
+ },
+ accordian: 'Divider',
+ },
+ dividerStyle: {
+ type: 'switch',
+ displayName: 'Style',
+ validation: {
+ schema: { type: 'string' },
+ },
+ options: [
+ { displayName: 'Solid', value: 'solid' },
+ { displayName: 'Dashed', value: 'dashed' },
+ ],
+ accordian: 'Divider',
+ },
+ labelAlignment: {
+ type: 'switch',
+ displayName: 'Label alignment',
+ validation: { schema: { type: 'string' }, defaultValue: 'left' },
+ isIcon: true,
+ showLabel: true,
+ options: [
+ { displayName: 'alignleftinspector', value: 'left', iconName: 'alignleftinspector' },
+ { displayName: 'alignhorizontalcenter', value: 'center', iconName: 'alignhorizontalcenter' },
+ { displayName: 'alignrightinspector', value: 'right', iconName: 'alignrightinspector' },
+ ],
+ accordian: 'Divider',
+ isFxNotRequired: true,
+ },
+ labelColor: {
+ type: 'color',
+ displayName: 'Label Color',
+ validation: {
+ schema: { type: 'string' },
+ },
+ accordian: 'Divider',
+ },
+ boxShadow: {
+ type: 'boxShadow',
+ displayName: 'Box Shadow',
+ validation: {
+ schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
+ defaultValue: '0px 0px 0px 0px #00000040',
+ },
+ accordian: 'Divider',
+ },
+ padding: {
+ type: 'switch',
+ displayName: 'Padding',
+ validation: {
+ schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
+ defaultValue: 'default',
+ },
+ isFxNotRequired: true,
+ options: [
+ { displayName: 'Default', value: 'default' },
+ { displayName: 'None', value: 'none' },
+ ],
+ accordian: 'container',
},
},
exposedVariables: {
@@ -39,11 +139,19 @@ export const dividerConfig = {
showOnDesktop: { value: '{{true}}' },
showOnMobile: { value: '{{false}}' },
},
- properties: {},
+ properties: {
+ label: { value: '' },
+ visibility: { value: '{{true}}' },
+ tooltip: { value: '' },
+ },
events: [],
styles: {
- visibility: { value: '{{true}}' },
- dividerColor: { value: '#000000' },
+ dividerColor: { value: '#CCD1D5' },
+ labelAlignment: { value: 'center' },
+ dividerStyle: { value: 'solid' },
+ labelColor: { value: '#6A727C' },
+ padding: { value: 'default' },
+ boxShadow: { value: '0px 0px 0px 0px #00000040' },
},
},
};
diff --git a/server/src/modules/apps/services/widget-config/verticalDivider.js b/server/src/modules/apps/services/widget-config/verticalDivider.js
index e43b81adf7..df426c7b5f 100644
--- a/server/src/modules/apps/services/widget-config/verticalDivider.js
+++ b/server/src/modules/apps/services/widget-config/verticalDivider.js
@@ -1,17 +1,34 @@
export const verticalDividerConfig = {
name: 'VerticalDivider',
- displayName: 'Vertical Divider',
+ displayName: 'Vertical divider',
description: 'Vertical line separator',
component: 'VerticalDivider',
defaultSize: {
- width: 2,
+ width: 1,
height: 100,
},
others: {
showOnDesktop: { type: 'toggle', displayName: 'Show on desktop' },
showOnMobile: { type: 'toggle', displayName: 'Show on mobile' },
},
- properties: {},
+ properties: {
+ visibility: {
+ type: 'toggle',
+ displayName: 'Visibility',
+ validation: {
+ schema: { type: 'boolean' },
+ defaultValue: true,
+ },
+ section: 'additionalActions',
+ },
+ tooltip: {
+ type: 'code',
+ displayName: 'Tooltip',
+ validation: { schema: { type: 'string' }, defaultValue: 'Tooltip text' },
+ section: 'additionalActions',
+ placeholder: 'Enter tooltip text',
+ },
+ },
events: {},
styles: {
dividerColor: {
@@ -21,14 +38,42 @@ export const verticalDividerConfig = {
schema: { type: 'string' },
defaultValue: '#000000',
},
+ accordian: 'Divider',
},
- visibility: {
- type: 'toggle',
- displayName: 'Visibility',
+ dividerStyle: {
+ type: 'switch',
+ displayName: 'Style',
validation: {
- schema: { type: 'boolean' },
- defaultValue: true,
+ schema: { type: 'string' },
},
+ options: [
+ { displayName: 'Solid', value: 'solid' },
+ { displayName: 'Dashed', value: 'dashed' },
+ ],
+ accordian: 'Divider',
+ },
+ boxShadow: {
+ type: 'boxShadow',
+ displayName: 'Box Shadow',
+ validation: {
+ schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
+ defaultValue: '0px 0px 0px 0px #00000040',
+ },
+ accordian: 'Divider',
+ },
+ padding: {
+ type: 'switch',
+ displayName: 'Padding',
+ validation: {
+ schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
+ defaultValue: 'default',
+ },
+ isFxNotRequired: true,
+ options: [
+ { displayName: 'Default', value: 'default' },
+ { displayName: 'None', value: 'none' },
+ ],
+ accordian: 'container',
},
},
exposedVariables: {
@@ -39,11 +84,16 @@ export const verticalDividerConfig = {
showOnDesktop: { value: '{{true}}' },
showOnMobile: { value: '{{false}}' },
},
- properties: {},
+ properties: {
+ visibility: { value: '{{true}}' },
+ tooltip: { value: '' },
+ },
events: [],
styles: {
- visibility: { value: '{{true}}' },
- dividerColor: { value: '#000000' },
+ dividerColor: { value: '#CCD1D5' },
+ dividerStyle: { value: 'solid' },
+ padding: { value: 'default' },
+ boxShadow: { value: '0px 0px 0px 0px #00000040' },
},
},
};