Skip to content

Commit

Permalink
FEAT: Add readonly support for custom RJSF widgets and transform LLMW…
Browse files Browse the repository at this point in the history
…hisperer v2 JSON schema form for cloud (#1059)

* Support 'readonly' parameter for all custom RJSF widgets

* Transform the JSON schema for the LLM Whisperer V2 adapter for cloud

* Fixed Eslint issues

* Code quality improvement

* Allow JSON schema transform for LLMW V2 only for paid plan users

* Allow JSON schema transform for LLMW V2 only for paid plan users

* Fix sonar issue

---------

Co-authored-by: vishnuszipstack <[email protected]>
Co-authored-by: Jaseem Jas <[email protected]>
  • Loading branch information
3 people authored Jan 23, 2025
1 parent 104a82b commit 89697c4
Show file tree
Hide file tree
Showing 17 changed files with 193 additions and 24 deletions.
37 changes: 36 additions & 1 deletion frontend/src/components/input-output/add-source/AddSource.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ import { EmptyState } from "../../widgets/empty-state/EmptyState";
import { ConfigureDs } from "../configure-ds/ConfigureDs";
import { useExceptionHandler } from "../../../hooks/useExceptionHandler";

let transformLlmWhispererJsonSchema;
let LLMW_V2_ID;
let PLAN_TYPES;
let unstractSubscriptionPlanStore;
try {
transformLlmWhispererJsonSchema =
require("../../../plugins/unstract-subscription/helper/transformLlmWhispererJsonSchema").transformLlmWhispererJsonSchema;
LLMW_V2_ID =
require("../../../plugins/unstract-subscription/helper/transformLlmWhispererJsonSchema").LLMW_V2_ID;
PLAN_TYPES =
require("../../../plugins/unstract-subscription/helper/constants").PLAN_TYPES;
unstractSubscriptionPlanStore = require("../../../plugins/store/unstract-subscription-plan-store");
} catch (err) {
// Ignore if not available
}

function AddSource({
selectedSourceId,
selectedSourceName,
Expand All @@ -32,6 +48,13 @@ function AddSource({
const axiosPrivate = useAxiosPrivate();
const handleException = useExceptionHandler();

let planType;
if (unstractSubscriptionPlanStore?.useUnstractSubscriptionPlanStore) {
planType = unstractSubscriptionPlanStore?.useUnstractSubscriptionPlanStore(
(state) => state?.unstractSubscriptionPlan?.planType
);
}

useEffect(() => {
if (!selectedSourceId) {
setSpec({});
Expand All @@ -56,7 +79,19 @@ function AddSource({
.then((res) => {
const data = res?.data;
setFormData(metadata || {});
setSpec(data?.json_schema || {});

if (
LLMW_V2_ID &&
transformLlmWhispererJsonSchema &&
PLAN_TYPES &&
selectedSourceId === LLMW_V2_ID &&
planType === PLAN_TYPES?.PAID
) {
setSpec(transformLlmWhispererJsonSchema(data?.json_schema || {}));
} else {
setSpec(data?.json_schema || {});
}

if (data?.oauth) {
setOAuthProvider(data?.python_social_auth_backend);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const AltDateTimeWidget = ({
label,
schema,
required,
readonly,
}) => {
const description = schema?.description || "";
const handleDateChange = (date) => {
Expand All @@ -34,10 +35,12 @@ const AltDateTimeWidget = ({
id={id}
value={value ? moment(value) : null}
onChange={handleDateChange}
disabled={readonly}
/>
<TimePicker
value={value ? moment(value) : null}
onChange={handleTimeChange}
disabled={readonly}
/>
</RjsfWidgetLayout>
);
Expand All @@ -49,7 +52,8 @@ AltDateTimeWidget.propTypes = {
onChange: PropTypes.func.isRequired,
label: PropTypes.string.isRequired,
schema: PropTypes.object.isRequired,
required: PropTypes.bool,
required: PropTypes.bool.isRequired,
readonly: PropTypes.bool.isRequired,
};

export { AltDateTimeWidget };
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import PropTypes from "prop-types";

import { RjsfWidgetLayout } from "../../../layouts/rjsf-widget-layout/RjsfWidgetLayout.jsx";

const AltDateWidget = ({ id, value, onChange, label, schema, required }) => {
const AltDateWidget = (props) => {
const { id, value, onChange, label, schema, required, readonly } = props;
const description = schema?.description || "";

const handleDateChange = (date) => {
Expand All @@ -21,6 +22,7 @@ const AltDateWidget = ({ id, value, onChange, label, schema, required }) => {
id={id}
value={value ? moment(value) : null}
onChange={handleDateChange}
disabled={readonly}
/>
</RjsfWidgetLayout>
);
Expand All @@ -33,6 +35,7 @@ AltDateWidget.propTypes = {
label: PropTypes.string.isRequired,
schema: PropTypes.object.isRequired,
required: PropTypes.bool,
readonly: PropTypes.bool.isRequired,
};

export { AltDateWidget };
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { RjsfWidgetLayout } from "../../../layouts/rjsf-widget-layout/RjsfWidget
import "./ArrayField.css";

const ArrayField = (props) => {
const { schema, formData, onChange, required } = props;
const { schema, formData, onChange, required, readonly } = props;
const [dropdownList, setDropdownList] = useState([]);
const [options, setOptions] = useState([]);

Expand Down Expand Up @@ -54,6 +54,7 @@ const ArrayField = (props) => {
value={formData}
onChange={handleChange}
options={options}
disabled={readonly}
/>
</RjsfWidgetLayout>
);
Expand All @@ -65,6 +66,7 @@ ArrayField.propTypes = {
formData: PropTypes.array,
onChange: PropTypes.func.isRequired,
required: PropTypes.bool,
readonly: PropTypes.bool.isRequired,
};

export { ArrayField };
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
import { Checkbox, Space, Typography } from "antd";
import PropTypes from "prop-types";

import "./CheckboxWidget.css";
import CustomMarkdown from "../../helpers/custom-markdown/CustomMarkdown";
const CheckboxWidget = ({ id, value, onChange, label, schema, required }) => {
const CheckboxWidget = ({
id,
value,
onChange,
label,
schema,
required,
readonly,
}) => {
const description = schema?.description || "";
const handleCheckboxChange = (event) => {
onChange(event.target.checked);
};

return (
<Space direction="vertical" className="checkbox-widget-main" size={0}>
<Checkbox id={id} checked={value} onChange={handleCheckboxChange}>
<Checkbox
id={id}
checked={value}
onChange={handleCheckboxChange}
disabled={readonly}
>
<Typography>
{required && <span className="form-item-required">* </span>}
{label}
Expand All @@ -34,6 +48,7 @@ CheckboxWidget.propTypes = {
label: PropTypes.string.isRequired,
schema: PropTypes.object.isRequired,
required: PropTypes.bool,
readonly: PropTypes.bool.isRequired,
};

export { CheckboxWidget };
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const CheckboxesWidget = ({
label,
schema,
required,
readonly,
}) => {
const description = schema?.description || "";
const handleCheckboxChange = (optionValue) => {
Expand All @@ -35,6 +36,7 @@ const CheckboxesWidget = ({
key={option.value}
checked={value?.includes(option.value)}
onChange={() => handleCheckboxChange(option.value)}
disabled={readonly}
>
{option.label}
</Checkbox>
Expand All @@ -51,6 +53,7 @@ CheckboxesWidget.propTypes = {
label: PropTypes.string.isRequired,
schema: PropTypes.object.isRequired,
required: PropTypes.bool,
readonly: PropTypes.bool.isRequired,
};

export { CheckboxesWidget };
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ import { Input } from "antd";

import { RjsfWidgetLayout } from "../../../layouts/rjsf-widget-layout/RjsfWidgetLayout.jsx";

const ColorWidget = ({ id, value, onChange, schema, label, required }) => {
const ColorWidget = ({
id,
value,
onChange,
schema,
label,
required,
readonly,
}) => {
const description = schema?.description || "";

const handleColorChange = (event) => {
Expand All @@ -16,7 +24,13 @@ const ColorWidget = ({ id, value, onChange, schema, label, required }) => {
description={description}
required={required}
>
<Input type="color" id={id} value={value} onChange={handleColorChange} />
<Input
type="color"
id={id}
value={value}
onChange={handleColorChange}
disabled={readonly}
/>
</RjsfWidgetLayout>
);
};
Expand All @@ -28,6 +42,7 @@ ColorWidget.propTypes = {
schema: PropTypes.object.isRequired,
label: PropTypes.string.isRequired,
required: PropTypes.bool,
readonly: PropTypes.bool.isRequired,
};

export { ColorWidget };
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ import PropTypes from "prop-types";

import { RjsfWidgetLayout } from "../../../layouts/rjsf-widget-layout/RjsfWidgetLayout.jsx";

const DateTimeWidget = ({ id, value, onChange, label, schema, required }) => {
const DateTimeWidget = ({
id,
value,
onChange,
label,
schema,
required,
readonly,
}) => {
const description = schema?.description || "";
const handleDateTimeChange = (dateTime) => {
onChange(dateTime?.toISOString());
Expand All @@ -21,6 +29,7 @@ const DateTimeWidget = ({ id, value, onChange, label, schema, required }) => {
id={id}
value={value ? moment(value) : null}
onChange={handleDateTimeChange}
disabled={readonly}
/>
</RjsfWidgetLayout>
);
Expand All @@ -33,6 +42,7 @@ DateTimeWidget.propTypes = {
label: PropTypes.string.isRequired,
schema: PropTypes.object.isRequired,
required: PropTypes.bool,
readonly: PropTypes.bool.isRequired,
};

export { DateTimeWidget };
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ import PropTypes from "prop-types";

import { RjsfWidgetLayout } from "../../../layouts/rjsf-widget-layout/RjsfWidgetLayout.jsx";

const DateWidget = ({ id, value, onChange, label, schema, required }) => {
const DateWidget = ({
id,
value,
onChange,
label,
schema,
required,
readonly,
}) => {
const description = schema?.description || "";
const handleDateChange = (date) => {
onChange(date?.toISOString());
Expand All @@ -20,6 +28,7 @@ const DateWidget = ({ id, value, onChange, label, schema, required }) => {
id={id}
value={value ? moment(value) : null}
onChange={handleDateChange}
disabled={readonly}
/>
</RjsfWidgetLayout>
);
Expand All @@ -32,6 +41,7 @@ DateWidget.propTypes = {
label: PropTypes.string.isRequired,
schema: PropTypes.object.isRequired,
required: PropTypes.bool,
readonly: PropTypes.bool.isRequired,
};

export { DateWidget };
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ import PropTypes from "prop-types";

import { RjsfWidgetLayout } from "../../../layouts/rjsf-widget-layout/RjsfWidgetLayout.jsx";

const EmailWidget = ({ id, value, onChange, label, schema, required }) => {
const EmailWidget = ({
id,
value,
onChange,
label,
schema,
required,
readonly,
}) => {
const description = schema?.description || "";
const handleEmailChange = (event) => {
onChange(event.target.value);
Expand All @@ -15,7 +23,13 @@ const EmailWidget = ({ id, value, onChange, label, schema, required }) => {
description={description}
required={required}
>
<Input type="email" id={id} value={value} onChange={handleEmailChange} />
<Input
type="email"
id={id}
value={value}
onChange={handleEmailChange}
disabled={readonly}
/>
</RjsfWidgetLayout>
);
};
Expand All @@ -27,6 +41,7 @@ EmailWidget.propTypes = {
label: PropTypes.string.isRequired,
schema: PropTypes.object.isRequired,
required: PropTypes.bool,
readonly: PropTypes.bool.isRequired,
};

export { EmailWidget };
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import PropTypes from "prop-types";

import { RjsfWidgetLayout } from "../../../layouts/rjsf-widget-layout/RjsfWidgetLayout.jsx";

const FileWidget = ({ id, onChange, label, schema, required }) => {
const FileWidget = ({ id, onChange, label, schema, required, readonly }) => {
const description = schema?.description || "";
const handleFileChange = (info) => {
if (info.file.status === "done") {
Expand All @@ -19,7 +19,7 @@ const FileWidget = ({ id, onChange, label, schema, required }) => {
description={description}
required={required}
>
<Upload id={id} onChange={handleFileChange}>
<Upload id={id} onChange={handleFileChange} disabled={readonly}>
<Button icon={<UploadOutlined />}>Upload File</Button>
</Upload>
</RjsfWidgetLayout>
Expand All @@ -32,6 +32,7 @@ FileWidget.propTypes = {
label: PropTypes.string.isRequired,
schema: PropTypes.object.isRequired,
required: PropTypes.bool,
readonly: PropTypes.bool.isRequired,
};

export { FileWidget };
Loading

0 comments on commit 89697c4

Please sign in to comment.