Merge pull request #11069 from ToolJet/fix/ce-app-builder

Merge fixes
This commit is contained in:
Johnson Cherian 2024-10-22 19:09:26 +05:30 committed by GitHub
commit 1442a11689
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 338 additions and 30 deletions

View file

@ -205,7 +205,6 @@ export const createQueryPanelSlice = (set, get) => ({
setPreviewPanelExpanded,
executeRunPycode,
runTransformation,
executeWorkflow,
executeMultilineJS,
} = queryPanel;
const { onEvent } = eventsSlice;
@ -297,14 +296,6 @@ export const createQueryPanelSlice = (set, get) => ({
queryExecutionPromise = executeMultilineJS(query.options.code, query?.id, false, mode, parameters);
} else if (query.kind === 'runpy') {
queryExecutionPromise = executeRunPycode(query.options.code, query, false, mode, queryState);
} else if (query.kind === 'workflows') {
queryExecutionPromise = executeWorkflow(
moduleId,
query.options.workflowId,
query.options.blocking,
query.options?.params,
(currentAppEnvironmentId ?? environmentId) || selectedEnvironment?.id //TODO: currentAppEnvironmentId may no longer required. Need to check
);
} else {
queryExecutionPromise = dataqueryService.run(
queryId,
@ -465,7 +456,6 @@ export const createQueryPanelSlice = (set, get) => ({
setPreviewPanelExpanded,
executeRunPycode,
runTransformation,
executeWorkflow,
executeMultilineJS,
setIsPreviewQueryLoading,
} = queryPanel;
@ -514,14 +504,6 @@ export const createQueryPanelSlice = (set, get) => ({
queryExecutionPromise = executeMultilineJS(query.options.code, query?.id, true, '', parameters);
} else if (query.kind === 'runpy') {
queryExecutionPromise = executeRunPycode(query.options.code, query, true, 'edit', queryState);
} else if (query.kind === 'workflows') {
queryExecutionPromise = executeWorkflow(
moduleId,
query.options.workflowId,
query.options.blocking,
query.options?.params,
(currentAppEnvironmentId ?? environmentId) || selectedEnvironment?.id //TODO: currentAppEnvironmentId may no longer required. Need to check
);
} else {
queryExecutionPromise = dataqueryService.preview(query, options, currentVersionId, currentAppEnvironmentId);
}

View file

@ -0,0 +1,22 @@
import React from 'react';
import isEmpty from 'lodash/isEmpty';
import Accordion from '@/_ui/Accordion';
const AccordionForm = ({ formComponent, getLayout }) => {
const sections = Object.keys(formComponent)
.map((key) => ({
title: formComponent[key].title,
inputs: formComponent[key].inputs,
}))
.filter(({ inputs }) => inputs && !isEmpty(inputs));
const items = sections.map(({ title, inputs }) => ({
title: title,
isOpen: true,
children: getLayout(inputs),
}));
return <Accordion items={items} />;
};
export default AccordionForm;

View file

@ -8,13 +8,13 @@ import OAuth from '@/_ui/OAuth';
import Toggle from '@/_ui/Toggle';
import OpenApi from '@/_ui/OpenAPI';
import { Checkbox, CheckboxGroup } from '@/_ui/CheckBox';
import CodeHinter from '@/Editor/CodeEditor';
import CodeHinter from '@/AppBuilder/CodeEditor';
import GoogleSheets from '@/_components/Googlesheets';
import Slack from '@/_components/Slack';
import Zendesk from '@/_components/Zendesk';
import { ConditionFilter, CondtionSort, MultiColumn } from '@/_components/MultiConditions';
import Salesforce from '@/_components/Salesforce';
import ToolJetDbOperations from '@/Editor/QueryManager/QueryEditors/TooljetDatabase/ToolJetDbOperations';
import ToolJetDbOperations from '@/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/ToolJetDbOperations';
import { orgEnvironmentVariableService, orgEnvironmentConstantService } from '../_services';
import { find, isEmpty } from 'lodash';
import { ButtonSolid } from './AppButton';

View file

@ -31,17 +31,18 @@ const AccordionItem = ({ open = true, index, title, children }) => {
}
return (
<div className="accordion-item">
<h2 onClick={() => setShow(!show)} className="accordion-header" id={`heading-${index}`}>
<button
className={cx('accordion-button', { collapsed: !show })}
type="button"
data-bs-toggle="collapse"
data-bs-target={`collapse-${index}`}
aria-expanded="false"
data-cy={`widget-accordion-${title.toLowerCase()}`}
>
<h2 className="accordion-header" id={`heading-${index}`} data-cy={`widget-accordion-${title.toLowerCase()}`}>
<div className={cx('accordion-button inspector')}>
<span className="text-capitalize accordion-title-text">{title}</span>
</button>
<div
type="button"
data-bs-toggle="collapse"
data-bs-target={`collapse-${index}`}
aria-expanded="false"
className={cx('accordion-item-trigger', { collapsed: !show })}
onClick={() => setShow((prev) => !prev)}
></div>
</div>
</h2>
<div
id={`collapse-${index}`}

View file

@ -0,0 +1,74 @@
import React from 'react';
import { ButtonSolid } from '@/_ui/AppButton/AppButton';
import AddRectangle from '@/_ui/Icon/bulkIcons/AddRectangle';
import CodeHinter from '@/Editor/CodeEditor';
import InfoIcon from '@assets/images/icons/info.svg';
import Trash from '@/_ui/Icon/solidIcons/Trash';
import Select from '@/_ui/Select';
import Input from '@/_ui/Input';
import '@/_ui/Sort/sortStyles.scss';
export default ({ options, addNewKeyValuePair, removeKeyValuePair, keyValuePairValueChanged, buttonText }) => {
const darkMode = localStorage.getItem('darkMode') === 'true';
const sortOptions = [
{ value: 'asc', label: 'Ascending' },
{ value: 'desc', label: 'Descending' },
];
return (
<div>
{options.length === 0 && (
<div className="empty-key-value">
<InfoIcon style={{ width: '16px', marginRight: '5px' }} />
<span>There are no key value pairs added</span>
</div>
)}
{options.map((option, index) => {
return (
<div className="d-flex" key={index}>
<div className="d-flex mb-2 justify-content-between w-100">
<div className="w-100 sort-input">
<Input
value={option[0]}
className="form-control"
type="text"
placeholder="Field"
style={{ height: '32px' }}
onChange={(e) => keyValuePairValueChanged(e.target.value, 0, index)}
/>
</div>
<div className="w-100 sort-input">
<Select
options={sortOptions}
value={sortOptions.find((opt) => opt.value === option[1])}
onChange={(value) => keyValuePairValueChanged(value, 1, index)}
width={'100%'}
placeholder="Select direction"
/>
</div>
</div>
<button
className={`d-flex justify-content-center align-items-center delete-field-option bg-transparent border-0 rounded-0 border-top border-bottom border-end border-start rounded-start rounded-end trash ${
darkMode ? 'delete-field-option-dark' : ''
}`}
role="button"
onClick={() => {
removeKeyValuePair(index);
}}
>
<Trash fill="var(--slate9)" style={{ height: '16px' }} />
</button>
</div>
);
})}
<ButtonSolid
variant="ghostBlue"
size="sm"
onClick={() => addNewKeyValuePair(options)}
style={{ gap: '0px', padding: '2px 8px' }}
>
<AddRectangle width="15" fill="#3E63DD" opacity="1" secondaryFill="#ffffff" />
&nbsp;&nbsp;{buttonText}
</ButtonSolid>
</div>
);
};

View file

@ -0,0 +1,80 @@
import React from 'react';
import Input from '../Input';
import Trash from '@/_ui/Icon/solidIcons/Trash';
import { ButtonSolid } from '@/_ui/AppButton/AppButton';
import AddRectangle from '@/_ui/Icon/bulkIcons/AddRectangle';
import InfoIcon from '@assets/images/icons/info.svg';
import '@/_ui/Sort/sortStyles.scss';
import Select from '@/_ui/Select';
export default ({
options,
addNewKeyValuePair,
removeKeyValuePair,
keyValuePairValueChanged,
workspaceConstants,
isDisabled,
width,
}) => {
const darkMode = localStorage.getItem('darkMode') === 'true';
const sortOptions = [
{ value: 'asc', label: 'Ascending' },
{ value: 'desc', label: 'Descending' },
];
return (
<div className="table-content-wrapper">
{options.length === 0 && (
<div className="empty-key-value">
<InfoIcon style={{ width: '16px', marginRight: '5px' }} />
<span>There are no key value pairs added</span>
</div>
)}
{options.map((option, index) => (
<div className="d-flex align-items-top row-container query-manager-border-color" key={index}>
<Input
value={option[0]}
className="form-control"
type="text"
placeholder="Field"
style={{ width: width ? width : '300px', borderTopRightRadius: '0px', borderBottomRightRadius: '0px' }}
onChange={(e) => keyValuePairValueChanged(e.target.value, 0, index)}
/>
<Select
options={sortOptions}
value={sortOptions.find((opt) => opt.value === option[1])}
onChange={(value) => keyValuePairValueChanged(value, 1, index)}
width={'316px'}
height={'35px'}
placeholder="Select direction"
/>
<button
className={`d-flex justify-content-center align-items-center delete-field-option bg-transparent border-0 rounded-0 border-top border-bottom border-end rounded-end ${
darkMode ? 'delete-field-option-dark' : ''
}`}
style={{ height: '35px' }}
role="button"
disabled={isDisabled}
onClick={() => removeKeyValuePair(index)}
>
<Trash fill="var(--slate9)" style={{ height: '16px' }} />
</button>
</div>
))}
<div className="d-flex mb-2" style={{ height: '16px' }}>
<ButtonSolid
variant="ghostBlue"
size="sm"
onClick={() => addNewKeyValuePair(options)}
style={{ gap: '0px', paddingTop: '2px', paddingRight: '8px', paddingBottom: '2px', paddingLeft: '8px' }}
disabled={isDisabled}
>
<AddRectangle width="15" fill="#3E63DD" opacity="1" secondaryFill="#ffffff" />
&nbsp;&nbsp;Add
</ButtonSolid>
</div>
</div>
);
};

View file

@ -0,0 +1,53 @@
import React from 'react';
import _ from 'lodash';
import QueryEditor from './QueryEditor';
import SourceEditor from './SourceEditor';
import { deepClone } from '@/_helpers/utilities/utils.helpers';
export default ({
getter,
options = [['', '']],
optionchanged,
currentState,
isRenderedAsQueryEditor,
workspaceConstants,
isDisabled,
buttonText,
width,
}) => {
function addNewKeyValuePair(options) {
const newPairs = [...options, ['', '']];
optionchanged(getter, newPairs);
}
function removeKeyValuePair(index) {
options.splice(index, 1);
optionchanged(getter, options);
}
function keyValuePairValueChanged(value, keyIndex, index) {
if (!isRenderedAsQueryEditor) {
const newOptions = deepClone(options);
newOptions[index][keyIndex] = value;
options.length - 1 === index ? addNewKeyValuePair(newOptions) : optionchanged(getter, newOptions);
} else {
options[index][keyIndex] = value;
optionchanged(getter, options);
}
}
const commonProps = {
options,
addNewKeyValuePair,
removeKeyValuePair,
keyValuePairValueChanged,
isDisabled,
buttonText,
};
return isRenderedAsQueryEditor ? (
<QueryEditor {...commonProps} />
) : (
<SourceEditor {...commonProps} workspaceConstants={workspaceConstants} width={width} />
);
};

View file

@ -0,0 +1,96 @@
.query-manager-border-color {
input.form-control,
textarea,
.input-control {
gap: 16px !important;
background: var(--base) !important;
border: 1px solid var(--slate7) !important;
border-radius: 6px;
margin-bottom: 4px !important;
color: var(--slate12) !important;
transition: none;
height: 35px;
padding-left: 0.4375rem;
padding-right: 0.4375rem;
padding-top: 0.75rem;
padding-bottom: 0.75rem;
overflow-x: 'auto';
white-space: 'nowrap';
&:hover {
background: var(--slate1) !important;
border: 1px solid var(--slate8) !important;
-webkit-box-shadow: none !important;
box-shadow: none !important;
outline: none;
}
&:focus-visible {
background: var(--indigo2) !important;
border: 1px solid var(--indigo9) !important;
box-shadow: none !important;
}
&.input-error-border {
border-color: #DB4324 !important;
}
&:-webkit-autofill {
box-shadow: 0 0 0 1000px var(--base) inset !important;
-webkit-text-fill-color: var(--slate12) !important;
&:hover {
box-shadow: 0 0 0 1000px var(--slate1) inset !important;
-webkit-text-fill-color: var(--slate12) !important;
}
&:focus-visible {
box-shadow: 0 0 0 1000px var(--indigo2) inset !important;
-webkit-text-fill-color: var(--slate12) !important;
}
}
}
}
.empty-key-value {
border-radius: 6px;
padding: 10px;
text-align: center;
width: 625px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10px;
color: #687076;
font-size: 12px;
font-weight: 400;
line-height: 20px;
border: 1px dashed #E6E8EB;
}
.trash {
height: 32px;
display: flex;
justify-content: 'center';
align-items: 'center';
}
.sort-input,
.table-content-wrapper{
.tj-app-input{
.form-control{
border-radius: 6px 0px 0px 6px !important;
}
}
}
.sort-input,
.table-content-wrapper{
.dark-theme.react-select__control{
border-radius: 0px 6px 6px 0px !important;
}
}