From aa4cd1fc2e2279f9fd6e3c0a35b5366334faa705 Mon Sep 17 00:00:00 2001
From: Nithin David Thomas <1277421+nithindavid@users.noreply.github.com>
Date: Wed, 4 Dec 2024 00:26:38 -0800
Subject: [PATCH] chore: Exposes CSAs for Container widget (#11229)
* chore: Exposes CSAs for Container widget
* Introduces hook to expose variables
* Updates hook to expose variable after setting the state
* Update frontend/src/AppBuilder/_hooks/useExposeVariables.js
Co-authored-by: Kavin Venkatachalam <50441969+kavinvenkatachalam@users.noreply.github.com>
* Removes unwanted imports
* Exposing CSA to control component actions
* Moves CSA's to additional actions section
* Fixes wrong handle param
---------
Co-authored-by: Kavin Venkatachalam <50441969+kavinvenkatachalam@users.noreply.github.com>
---
.../Inspector/Components/DefaultComponent.jsx | 1 +
.../WidgetManager/widgets/container.js | 63 +++++++++++++------
frontend/src/AppBuilder/Widgets/Container.jsx | 31 +++++++--
.../AppBuilder/_hooks/useExposeVariables.js | 51 +++++++++++++++
.../Editor/WidgetManager/configs/container.js | 61 ++++++++++++------
server/src/helpers/widget-config/container.js | 63 +++++++++++++------
6 files changed, 206 insertions(+), 64 deletions(-)
create mode 100644 frontend/src/AppBuilder/_hooks/useExposeVariables.js
diff --git a/frontend/src/AppBuilder/RightSideBar/Inspector/Components/DefaultComponent.jsx b/frontend/src/AppBuilder/RightSideBar/Inspector/Components/DefaultComponent.jsx
index 74ae7c6e47..c183a644c0 100644
--- a/frontend/src/AppBuilder/RightSideBar/Inspector/Components/DefaultComponent.jsx
+++ b/frontend/src/AppBuilder/RightSideBar/Inspector/Components/DefaultComponent.jsx
@@ -12,6 +12,7 @@ import { shallow } from 'zustand/shallow';
const SHOW_ADDITIONAL_ACTIONS = [
'Text',
+ 'Container',
'TextInput',
'NumberInput',
'PasswordInput',
diff --git a/frontend/src/AppBuilder/WidgetManager/widgets/container.js b/frontend/src/AppBuilder/WidgetManager/widgets/container.js
index 32d4158ffc..dc2dcf34ec 100644
--- a/frontend/src/AppBuilder/WidgetManager/widgets/container.js
+++ b/frontend/src/AppBuilder/WidgetManager/widgets/container.js
@@ -15,6 +15,25 @@ export const containerConfig = {
loadingState: {
type: 'toggle',
displayName: 'Loading state',
+ section: 'additionalActions',
+ validation: {
+ schema: { type: 'boolean' },
+ defaultValue: false,
+ },
+ },
+ visibility: {
+ type: 'toggle',
+ displayName: 'Visibility',
+ section: 'additionalActions',
+ validation: {
+ schema: { type: 'boolean' },
+ defaultValue: true,
+ },
+ },
+ disabledState: {
+ type: 'toggle',
+ displayName: 'Disable',
+ section: 'additionalActions',
validation: {
schema: { type: 'boolean' },
defaultValue: false,
@@ -50,40 +69,44 @@ export const containerConfig = {
defaultValue: '#fff',
},
},
- visibility: {
- type: 'toggle',
- displayName: 'Visibility',
- validation: {
- schema: { type: 'boolean' },
- defaultValue: true,
- },
- },
- disabledState: {
- type: 'toggle',
- displayName: 'Disable',
- validation: {
- schema: { type: 'boolean' },
- },
- defaultValue: false,
- },
},
- exposedVariables: {},
+ exposedVariables: {
+ isVisible: true,
+ isDisabled: false,
+ isLoading: false,
+ },
+ actions: [
+ {
+ handle: 'setVisibility',
+ displayName: 'Set visibility',
+ params: [{ handle: 'disable', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
+ },
+ {
+ handle: 'setDisable',
+ displayName: 'Set disable',
+ params: [{ handle: 'setDisable', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
+ },
+ {
+ handle: 'setLoading',
+ displayName: 'Set loading',
+ params: [{ handle: 'setLoading', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
+ },
+ ],
definition: {
others: {
showOnDesktop: { value: '{{true}}' },
showOnMobile: { value: '{{false}}' },
},
properties: {
- visible: { value: '{{true}}' },
loadingState: { value: `{{false}}` },
+ visibility: { value: '{{true}}' },
+ disabledState: { value: '{{false}}' },
},
events: [],
styles: {
backgroundColor: { value: '#fff' },
borderRadius: { value: '4' },
borderColor: { value: '#fff' },
- visibility: { value: '{{true}}' },
- disabledState: { value: '{{false}}' },
},
},
};
diff --git a/frontend/src/AppBuilder/Widgets/Container.jsx b/frontend/src/AppBuilder/Widgets/Container.jsx
index b54b94c9a3..2b6f8008ed 100644
--- a/frontend/src/AppBuilder/Widgets/Container.jsx
+++ b/frontend/src/AppBuilder/Widgets/Container.jsx
@@ -1,9 +1,28 @@
import React, { useMemo } from 'react';
import { Container as ContainerComponent } from '@/AppBuilder/AppCanvas/Container';
import Spinner from '@/_ui/Spinner';
+import { useExposeState } from '@/AppBuilder/_hooks/useExposeVariables';
+
+export const Container = ({
+ id,
+ properties,
+ styles,
+ darkMode,
+ height,
+ width,
+ setExposedVariables,
+ setExposedVariable,
+}) => {
+ const { borderRadius, borderColor, boxShadow } = styles;
+
+ const { isDisabled, isVisible, isLoading } = useExposeState(
+ properties.loadingState,
+ properties.visibility,
+ properties.disabledState,
+ setExposedVariables,
+ setExposedVariable
+ );
-export const Container = ({ id, properties, styles, darkMode, height, width }) => {
- const { visibility, disabledState, borderRadius, borderColor, boxShadow } = styles;
const bgColor = useMemo(() => {
return {
backgroundColor:
@@ -16,19 +35,19 @@ export const Container = ({ id, properties, styles, darkMode, height, width }) =
borderRadius: borderRadius ? parseFloat(borderRadius) : 0,
border: `1px solid ${borderColor}`,
height,
- display: visibility ? 'flex' : 'none',
+ display: isVisible ? 'flex' : 'none',
overflow: 'hidden auto',
position: 'relative',
boxShadow,
};
return (
- {properties.loadingState ? (
+ {isLoading ? (
) : (
diff --git a/frontend/src/AppBuilder/_hooks/useExposeVariables.js b/frontend/src/AppBuilder/_hooks/useExposeVariables.js
new file mode 100644
index 0000000000..3c929f829b
--- /dev/null
+++ b/frontend/src/AppBuilder/_hooks/useExposeVariables.js
@@ -0,0 +1,51 @@
+import { useEffect, useState } from 'react';
+
+export const useExposeState = (loadingState, visibleState, disabledState, setExposedVariables, setExposedVariable) => {
+ const [isDisabled, setDisable] = useState(disabledState || false);
+ const [isVisible, setVisibility] = useState(visibleState || true);
+ const [isLoading, setLoading] = useState(loadingState || false);
+
+ // Effect to conditionally update state from properties passed to widget
+ useEffect(() => {
+ setDisable(disabledState);
+ }, [disabledState]);
+
+ useEffect(() => {
+ setVisibility(visibleState);
+ }, [visibleState]);
+
+ useEffect(() => {
+ setLoading(loadingState);
+ }, [loadingState]);
+
+ // exposed variables with state and async setters, happens on first time load
+ useEffect(() => {
+ setExposedVariables({
+ setDisable: async (value) => setDisable(value),
+ setVisibility: async (value) => setVisibility(value),
+ setLoading: async (value) => setLoading(value),
+ });
+ }, [setExposedVariables]);
+
+ //Side effect to state variables, these will run after the state is set and the values will be exposed
+ useEffect(() => {
+ setExposedVariable('isDisabled', isDisabled);
+ }, [isDisabled, setExposedVariable]);
+
+ useEffect(() => {
+ setExposedVariable('isVisible', isVisible);
+ }, [isVisible, setExposedVariable]);
+
+ useEffect(() => {
+ setExposedVariable('isLoading', isLoading);
+ }, [isLoading, setExposedVariable]);
+
+ return {
+ isDisabled,
+ setDisable,
+ isVisible,
+ setVisibility,
+ isLoading,
+ setLoading,
+ };
+};
diff --git a/frontend/src/Editor/WidgetManager/configs/container.js b/frontend/src/Editor/WidgetManager/configs/container.js
index 32d4158ffc..062b2791c4 100644
--- a/frontend/src/Editor/WidgetManager/configs/container.js
+++ b/frontend/src/Editor/WidgetManager/configs/container.js
@@ -15,6 +15,25 @@ export const containerConfig = {
loadingState: {
type: 'toggle',
displayName: 'Loading state',
+ section: 'additionalActions',
+ validation: {
+ schema: { type: 'boolean' },
+ defaultValue: false,
+ },
+ },
+ visibility: {
+ type: 'toggle',
+ displayName: 'Visibility',
+ section: 'additionalActions',
+ validation: {
+ schema: { type: 'boolean' },
+ defaultValue: true,
+ },
+ },
+ disabledState: {
+ type: 'toggle',
+ section: 'additionalActions',
+ displayName: 'Disable',
validation: {
schema: { type: 'boolean' },
defaultValue: false,
@@ -50,32 +69,38 @@ export const containerConfig = {
defaultValue: '#fff',
},
},
- visibility: {
- type: 'toggle',
- displayName: 'Visibility',
- validation: {
- schema: { type: 'boolean' },
- defaultValue: true,
- },
- },
- disabledState: {
- type: 'toggle',
- displayName: 'Disable',
- validation: {
- schema: { type: 'boolean' },
- },
- defaultValue: false,
- },
},
- exposedVariables: {},
+ exposedVariables: {
+ isVisible: true,
+ isDisabled: false,
+ isLoading: false,
+ },
+ actions: [
+ {
+ handle: 'setVisibility',
+ displayName: 'Set visibility',
+ params: [{ handle: 'setVisibility', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
+ },
+ {
+ handle: 'setLoading',
+ displayName: 'Set disable',
+ params: [{ handle: 'setLoading', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
+ },
+ {
+ handle: 'setLoading',
+ displayName: 'Set loading',
+ params: [{ handle: 'setLoading', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
+ },
+ ],
definition: {
others: {
showOnDesktop: { value: '{{true}}' },
showOnMobile: { value: '{{false}}' },
},
properties: {
- visible: { value: '{{true}}' },
loadingState: { value: `{{false}}` },
+ visibility: { value: '{{true}}' },
+ disabledState: { value: '{{false}}' },
},
events: [],
styles: {
diff --git a/server/src/helpers/widget-config/container.js b/server/src/helpers/widget-config/container.js
index 32d4158ffc..ef7f60855d 100644
--- a/server/src/helpers/widget-config/container.js
+++ b/server/src/helpers/widget-config/container.js
@@ -15,6 +15,25 @@ export const containerConfig = {
loadingState: {
type: 'toggle',
displayName: 'Loading state',
+ section: 'additionalActions',
+ validation: {
+ schema: { type: 'boolean' },
+ defaultValue: false,
+ },
+ },
+ visibility: {
+ type: 'toggle',
+ displayName: 'Visibility',
+ section: 'additionalActions',
+ validation: {
+ schema: { type: 'boolean' },
+ defaultValue: true,
+ },
+ },
+ disabledState: {
+ type: 'toggle',
+ displayName: 'Disable',
+ section: 'additionalActions',
validation: {
schema: { type: 'boolean' },
defaultValue: false,
@@ -50,40 +69,44 @@ export const containerConfig = {
defaultValue: '#fff',
},
},
- visibility: {
- type: 'toggle',
- displayName: 'Visibility',
- validation: {
- schema: { type: 'boolean' },
- defaultValue: true,
- },
- },
- disabledState: {
- type: 'toggle',
- displayName: 'Disable',
- validation: {
- schema: { type: 'boolean' },
- },
- defaultValue: false,
- },
},
- exposedVariables: {},
+ exposedVariables: {
+ isVisible: true,
+ isDisabled: false,
+ isLoading: false,
+ },
+ actions: [
+ {
+ handle: 'setVisibility',
+ displayName: 'Set visibility',
+ params: [{ handle: 'setVisibility', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
+ },
+ {
+ handle: 'setDisable',
+ displayName: 'Set disable',
+ params: [{ handle: 'setDisable', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
+ },
+ {
+ handle: 'setLoading',
+ displayName: 'Set loading',
+ params: [{ handle: 'setLoading', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
+ },
+ ],
definition: {
others: {
showOnDesktop: { value: '{{true}}' },
showOnMobile: { value: '{{false}}' },
},
properties: {
- visible: { value: '{{true}}' },
loadingState: { value: `{{false}}` },
+ visibility: { value: '{{true}}' },
+ disabledState: { value: '{{false}}' },
},
events: [],
styles: {
backgroundColor: { value: '#fff' },
borderRadius: { value: '4' },
borderColor: { value: '#fff' },
- visibility: { value: '{{true}}' },
- disabledState: { value: '{{false}}' },
},
},
};