feat: action redesign, UQI upgrade S3 plugin config to dual zone format & sorting field responsiveness (#36090)
## Description Upgrade S3 plugin config to new format using SECTION_V2, SINGLE_COLUMN_ZONE, and DOUBLE_COLUMN_ZONE. Fixes #35484 ## Automation /ok-to-test tags="@tag.All" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/10720588484> > Commit: c66dce69902ae247b6444ff901fe2cf1595e8e34 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10720588484&attempt=3" target="_blank">Cypress dashboard</a>. > Tags: `@tag.All` > Spec: > <hr>Thu, 05 Sep 2024 15:04:31 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Enhanced sorting control with improved performance and maintainability. - New configuration option for specifying the expiration duration of signed URLs in the Amazon S3 plugin. - Updated UI layout for various actions (upload, delete, read) in the Amazon S3 plugin to improve organization and user experience. - Clarified labeling and structure in the Amazon S3 plugin for better user interaction. - **Bug Fixes** - Streamlined logic for adding and deleting sorting fields in the sorting component. - **Documentation** - Updated control types and structure in the Amazon S3 plugin configuration for clarity and usability. - **Style** - Improved responsiveness of the sorting control layout and Amazon S3 plugin UI. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
1cf452fafa
commit
205ba07d53
|
|
@ -1,9 +1,12 @@
|
|||
import React, { useEffect, useRef } from "react";
|
||||
import React, { useEffect, useMemo, useRef } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import FormControl from "pages/Editor/FormControl";
|
||||
import { Classes } from "@appsmith/ads-old";
|
||||
import styled from "styled-components";
|
||||
import { FieldArray, getFormValues } from "redux-form";
|
||||
import {
|
||||
FieldArray,
|
||||
getFormValues,
|
||||
type WrappedFieldArrayProps,
|
||||
} from "redux-form";
|
||||
import type { ControlProps } from "./BaseControl";
|
||||
import { getBindingOrConfigPathsForSortingControl } from "entities/Action/actionProperties";
|
||||
import { SortingSubComponent } from "./utils";
|
||||
|
|
@ -26,9 +29,6 @@ const columnFieldConfig: any = {
|
|||
initialValue: "",
|
||||
inputType: "TEXT",
|
||||
placeholderText: "Column name",
|
||||
customStyles: {
|
||||
// width: "280px",
|
||||
},
|
||||
};
|
||||
|
||||
// Form config for the order field
|
||||
|
|
@ -52,60 +52,42 @@ const orderFieldConfig: any = {
|
|||
],
|
||||
};
|
||||
|
||||
// main container for the fsorting component
|
||||
const SortingContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
`;
|
||||
|
||||
// container for the two sorting dropdown
|
||||
const SortingDropdownContainer = styled.div<{ size: string }>`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: min-content;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 5px;
|
||||
const SortingContainer = styled.div<{ isBreakpointSmall: boolean }>`
|
||||
display: grid;
|
||||
grid-template-columns: ${({ isBreakpointSmall }) =>
|
||||
isBreakpointSmall ? "1fr 50px" : "1fr 50px"};
|
||||
gap: 5px;
|
||||
align-items: center;
|
||||
> div {
|
||||
width: 250px;
|
||||
}
|
||||
${(props) =>
|
||||
props.size === "small" &&
|
||||
`
|
||||
// Hide the dropdown labels to decrease the width
|
||||
// The design system component has inline style hence the !important
|
||||
.t--form-control-DROP_DOWN .${Classes.TEXT} {
|
||||
display: none !important;
|
||||
}
|
||||
// Show the icons hidden initially
|
||||
.t--form-control-DROP_DOWN .remixicon-icon {
|
||||
display: initial;
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
||||
const SortingFields = styled.div<{ isBreakpointSmall: boolean }>`
|
||||
display: grid;
|
||||
grid-template-columns: ${({ isBreakpointSmall }) =>
|
||||
isBreakpointSmall ? "1fr" : "1fr 180px"};
|
||||
grid-template-rows: ${({ isBreakpointSmall }) =>
|
||||
isBreakpointSmall ? "1fr 1fr" : "1fr"};
|
||||
gap: 5px;
|
||||
`;
|
||||
|
||||
const ButtonWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
`;
|
||||
// container for the column dropdown section
|
||||
const ColumnDropdownContainer = styled.div``;
|
||||
|
||||
// Component for the icons
|
||||
const CenteredButton = styled(Button)``;
|
||||
export type SortingControlProps = ControlProps;
|
||||
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function SortingComponent(props: any) {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const formValues: any = useSelector((state) =>
|
||||
export type SortingComponentProps = WrappedFieldArrayProps &
|
||||
Pick<SortingControlProps, "configProperty" | "formName">;
|
||||
|
||||
function SortingComponent(props: SortingComponentProps) {
|
||||
const { configProperty, fields, formName } = props;
|
||||
|
||||
const formValues = useSelector((state) =>
|
||||
getFormValues(props.formName)(state),
|
||||
);
|
||||
|
||||
const onDeletePressed = (index: number) => {
|
||||
props.fields.remove(index);
|
||||
fields.remove(index);
|
||||
};
|
||||
|
||||
const targetRef = useRef<HTMLDivElement>(null);
|
||||
|
|
@ -113,105 +95,100 @@ function SortingComponent(props: any) {
|
|||
const isBreakpointSmall = size === "small";
|
||||
|
||||
useEffect(() => {
|
||||
// this path represents the path to the sortBy object, wherever the location is in the actionConfiguration object
|
||||
let sortingObjectPath;
|
||||
// if the path ends with .data which we expect it to.
|
||||
if (props.configProperty.endsWith(".data")) {
|
||||
if (configProperty.endsWith(".data")) {
|
||||
// we remove the .data and get the path of the sort object
|
||||
// NOTE: 5 is used because (.data) = 5
|
||||
sortingObjectPath = props.configProperty.substring(
|
||||
const sortingObjectPath = configProperty.substring(
|
||||
0,
|
||||
props.configProperty.length - 5,
|
||||
configProperty.length - 5,
|
||||
);
|
||||
}
|
||||
// sortDataValue is the path to the value (.data included) itself in the sort object
|
||||
const sortDataValue = get(formValues, props.configProperty);
|
||||
// sort object value is the path to the sort object itself.
|
||||
const sortObjectValue = get(formValues, sortingObjectPath);
|
||||
|
||||
// The reason we are making this check is to prevent new fields from being pushed when the form control is visited
|
||||
// for some reason the fields object is initially undefined in first render, before being initialized with the correct values after.
|
||||
// so we check to see if the sortObjectValue exist first (if the value has been initalized).
|
||||
if (!sortObjectValue) {
|
||||
return;
|
||||
}
|
||||
// sortDataValue is the path to the value (.data included) itself in the sort object
|
||||
const sortDataValue = get(formValues, configProperty);
|
||||
// sort object value is the path to the sort object itself.
|
||||
const sortObjectValue = get(formValues, sortingObjectPath);
|
||||
|
||||
// then we check if the redux fields have any items in it,
|
||||
// and we also check if the value exists in the redux state as an array and if that value has no items in it.
|
||||
// if they are both empty we want to push a new field.
|
||||
// We also want to check if the value is undefined, this means that the sort data value is non existent, if it is, we want to push a new field.
|
||||
if (
|
||||
(props.fields.length < 1 &&
|
||||
isArray(sortDataValue) &&
|
||||
sortDataValue.length < 1) ||
|
||||
(props.fields.length < 1 && !sortDataValue)
|
||||
) {
|
||||
props.fields.push({
|
||||
column: "",
|
||||
order: OrderDropDownValues.ASCENDING,
|
||||
});
|
||||
} else {
|
||||
onDeletePressed(props.index);
|
||||
// The reason we are making this check is to prevent new fields from being pushed when the form control is visited
|
||||
// for some reason the fields object is initially undefined in first render, before being initialized with the correct values after.
|
||||
// so we check to see if the sortObjectValue exist first (if the value has been initalized).
|
||||
if (sortObjectValue) {
|
||||
// then we check if the redux fields have any items in it,
|
||||
// and we also check if the value exists in the redux state as an array and if that value has no items in it.
|
||||
// if they are both empty we want to push a new field.
|
||||
// We also want to check if the value is undefined, this means that the sort data value is non existent, if it is, we want to push a new field.
|
||||
if (
|
||||
(fields.length < 1 &&
|
||||
isArray(sortDataValue) &&
|
||||
sortDataValue.length < 1) ||
|
||||
(fields.length < 1 && !sortDataValue)
|
||||
) {
|
||||
fields.push({
|
||||
column: "",
|
||||
order: OrderDropDownValues.ASCENDING,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [props.fields.length]);
|
||||
}, [fields.length]);
|
||||
|
||||
return (
|
||||
<SortingContainer className={`t--${props?.configProperty}`} ref={targetRef}>
|
||||
{props.fields &&
|
||||
props.fields.length > 0 &&
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
props.fields.map((field: any, index: number) => {
|
||||
<SortingContainer
|
||||
className={`t--${props?.configProperty}`}
|
||||
isBreakpointSmall={isBreakpointSmall}
|
||||
ref={targetRef}
|
||||
>
|
||||
{fields &&
|
||||
fields.length > 0 &&
|
||||
fields.map((field, index: number) => {
|
||||
const columnPath = getBindingOrConfigPathsForSortingControl(
|
||||
SortingSubComponent.Column,
|
||||
field,
|
||||
undefined,
|
||||
);
|
||||
const OrderPath = getBindingOrConfigPathsForSortingControl(
|
||||
|
||||
const orderPath = getBindingOrConfigPathsForSortingControl(
|
||||
SortingSubComponent.Order,
|
||||
field,
|
||||
undefined,
|
||||
);
|
||||
|
||||
return (
|
||||
<SortingDropdownContainer key={index} size={size}>
|
||||
<ColumnDropdownContainer>
|
||||
<React.Fragment key={index}>
|
||||
<SortingFields isBreakpointSmall={isBreakpointSmall}>
|
||||
<FormControl
|
||||
config={{
|
||||
...columnFieldConfig,
|
||||
customStyles: {
|
||||
width: "250px",
|
||||
width: "100%",
|
||||
},
|
||||
configProperty: `${columnPath}`,
|
||||
configProperty: columnPath,
|
||||
nestedFormControl: true,
|
||||
}}
|
||||
formName={props.formName}
|
||||
formName={formName}
|
||||
/>
|
||||
</ColumnDropdownContainer>
|
||||
<FormControl
|
||||
config={{
|
||||
...orderFieldConfig,
|
||||
configProperty: `${OrderPath}`,
|
||||
nestedFormControl: true,
|
||||
customStyles: {
|
||||
width: isBreakpointSmall ? "65px" : "250px",
|
||||
},
|
||||
optionWidth: isBreakpointSmall ? "250px" : undefined,
|
||||
}}
|
||||
formName={props.formName}
|
||||
/>
|
||||
{/* Component to render the delete icon */}
|
||||
<CenteredButton
|
||||
<FormControl
|
||||
config={{
|
||||
...orderFieldConfig,
|
||||
customStyles: {
|
||||
maxWidth: "180px",
|
||||
},
|
||||
configProperty: orderPath,
|
||||
nestedFormControl: true,
|
||||
}}
|
||||
formName={formName}
|
||||
/>
|
||||
</SortingFields>
|
||||
<Button
|
||||
data-testid={`t--sorting-delete-[${index}]`}
|
||||
isIconButton
|
||||
kind="tertiary"
|
||||
onClick={(e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
onClick={() => {
|
||||
onDeletePressed(index);
|
||||
}}
|
||||
size="md"
|
||||
startIcon="close-line"
|
||||
value={index}
|
||||
/>
|
||||
</SortingDropdownContainer>
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
<ButtonWrapper>
|
||||
|
|
@ -219,7 +196,7 @@ function SortingComponent(props: any) {
|
|||
data-testid={`t--sorting-add-field`}
|
||||
kind="tertiary"
|
||||
onClick={() =>
|
||||
props.fields.push({
|
||||
fields.push({
|
||||
column: "",
|
||||
order: OrderDropDownValues.ASCENDING,
|
||||
})
|
||||
|
|
@ -240,18 +217,18 @@ export default function SortingControl(props: SortingControlProps) {
|
|||
formName, // Name of the form, used by redux-form lib to store the data in redux store
|
||||
} = props;
|
||||
|
||||
const fieldArrayProps = useMemo(
|
||||
() => ({ configProperty, formName }),
|
||||
[configProperty, formName],
|
||||
);
|
||||
|
||||
return (
|
||||
<FieldArray
|
||||
component={SortingComponent}
|
||||
key={`${configProperty}`}
|
||||
name={`${configProperty}`}
|
||||
props={{
|
||||
configProperty,
|
||||
formName,
|
||||
}}
|
||||
key={configProperty}
|
||||
name={configProperty}
|
||||
props={fieldArrayProps}
|
||||
rerenderOnEveryChange={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export type SortingControlProps = ControlProps;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
{
|
||||
"identifier": "UPLOAD_FILE_FROM_BODY",
|
||||
"controlType": "SECTION",
|
||||
"controlType": "SECTION_V2",
|
||||
"conditionals": {
|
||||
"show": "{{actionConfiguration.formData.command.data === 'UPLOAD_FILE_FROM_BODY'}}"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"controlType": "SECTION",
|
||||
"label": "Select bucket to query",
|
||||
"controlType": "DOUBLE_COLUMN_ZONE",
|
||||
"children": [
|
||||
{
|
||||
"label": "Bucket name",
|
||||
|
|
@ -16,12 +15,17 @@
|
|||
"evaluationSubstitutionType": "TEMPLATE",
|
||||
"isRequired": true,
|
||||
"initialValue": ""
|
||||
},
|
||||
{
|
||||
"label": "Expiry duration of signed URL (minutes)",
|
||||
"configProperty": "actionConfiguration.formData.create.expiry.data",
|
||||
"controlType": "QUERY_DYNAMIC_INPUT_TEXT",
|
||||
"initialValue": "5"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"controlType": "SECTION",
|
||||
"label": "Query",
|
||||
"controlType": "DOUBLE_COLUMN_ZONE",
|
||||
"description": "Optional",
|
||||
"children": [
|
||||
{
|
||||
|
|
@ -45,13 +49,13 @@
|
|||
"value": "NO"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Expiry duration of signed URL (minutes)",
|
||||
"configProperty": "actionConfiguration.formData.create.expiry.data",
|
||||
"controlType": "QUERY_DYNAMIC_INPUT_TEXT",
|
||||
"initialValue": "5"
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"controlType": "SINGLE_COLUMN_ZONE",
|
||||
"description": "Optional",
|
||||
"children": [
|
||||
{
|
||||
"label": "Content",
|
||||
"configProperty": "actionConfiguration.formData.body.data",
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
{
|
||||
"identifier": "UPLOAD_MULTIPLE_FILES_FROM_BODY",
|
||||
"controlType": "SECTION",
|
||||
"controlType": "SECTION_V2",
|
||||
"conditionals": {
|
||||
"show": "{{actionConfiguration.formData.command.data === 'UPLOAD_MULTIPLE_FILES_FROM_BODY'}}"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"controlType": "SECTION",
|
||||
"label": "Select bucket to query",
|
||||
"controlType": "DOUBLE_COLUMN_ZONE",
|
||||
"children": [
|
||||
{
|
||||
"label": "Bucket name",
|
||||
|
|
@ -16,12 +15,17 @@
|
|||
"evaluationSubstitutionType": "TEMPLATE",
|
||||
"isRequired": true,
|
||||
"initialValue": ""
|
||||
},
|
||||
{
|
||||
"label": "Expiry duration of signed URL (minutes)",
|
||||
"configProperty": "actionConfiguration.formData.create.expiry.data",
|
||||
"controlType": "QUERY_DYNAMIC_INPUT_TEXT",
|
||||
"initialValue": "5"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"controlType": "SECTION",
|
||||
"label": "Query",
|
||||
"controlType": "DOUBLE_COLUMN_ZONE",
|
||||
"description": "Optional",
|
||||
"children": [
|
||||
{
|
||||
|
|
@ -45,13 +49,13 @@
|
|||
"value": "NO"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Expiry duration of signed URL (minutes)",
|
||||
"configProperty": "actionConfiguration.formData.create.expiry.data",
|
||||
"controlType": "QUERY_DYNAMIC_INPUT_TEXT",
|
||||
"initialValue": "5"
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"controlType": "SINGLE_COLUMN_ZONE",
|
||||
"description": "Optional",
|
||||
"children": [
|
||||
{
|
||||
"label": "Content",
|
||||
"configProperty": "actionConfiguration.formData.body.data",
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
{
|
||||
"identifier": "DELETE_FILE",
|
||||
"controlType": "SECTION",
|
||||
"controlType": "SECTION_V2",
|
||||
"conditionals": {
|
||||
"show": "{{actionConfiguration.formData.command.data === 'DELETE_FILE'}}"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"controlType": "SECTION",
|
||||
"label": "Select bucket to query",
|
||||
"controlType": "DOUBLE_COLUMN_ZONE",
|
||||
"children": [
|
||||
{
|
||||
"label": "Bucket name",
|
||||
|
|
@ -20,8 +19,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"controlType": "SECTION",
|
||||
"label": "Query",
|
||||
"controlType": "DOUBLE_COLUMN_ZONE",
|
||||
"description": "Optional",
|
||||
"children": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
{
|
||||
"identifier": "DELETE_MULTIPLE_FILES",
|
||||
"controlType": "SECTION",
|
||||
"controlType": "SECTION_V2",
|
||||
"conditionals": {
|
||||
"show": "{{actionConfiguration.formData.command.data === 'DELETE_MULTIPLE_FILES'}}"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"controlType": "SECTION",
|
||||
"label": "Select bucket to query",
|
||||
"controlType": "DOUBLE_COLUMN_ZONE",
|
||||
"children": [
|
||||
{
|
||||
"label": "Bucket name",
|
||||
|
|
@ -16,7 +15,12 @@
|
|||
"evaluationSubstitutionType": "TEMPLATE",
|
||||
"isRequired": true,
|
||||
"initialValue": ""
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"controlType": "SINGLE_COLUMN_ZONE",
|
||||
"children": [
|
||||
{
|
||||
"label": "List of Files",
|
||||
"configProperty": "actionConfiguration.formData.path.data",
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
{
|
||||
"identifier": "LIST",
|
||||
"controlType": "SECTION",
|
||||
"controlType": "SECTION_V2",
|
||||
"conditionals": {
|
||||
"show": "{{actionConfiguration.formData.command.data === 'LIST'}}"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"controlType": "SECTION",
|
||||
"label": "Select bucket to query",
|
||||
"controlType": "DOUBLE_COLUMN_ZONE",
|
||||
"children": [
|
||||
{
|
||||
"label": "Bucket name",
|
||||
|
|
@ -16,62 +15,17 @@
|
|||
"evaluationSubstitutionType": "TEMPLATE",
|
||||
"isRequired": true,
|
||||
"initialValue": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"controlType": "SECTION",
|
||||
"label": "Query",
|
||||
"description": "Optional",
|
||||
"children": [
|
||||
},
|
||||
{
|
||||
"label": "Prefix",
|
||||
"configProperty": "actionConfiguration.formData.list.prefix.data",
|
||||
"controlType": "QUERY_DYNAMIC_INPUT_TEXT",
|
||||
"initialValue": ""
|
||||
},
|
||||
{
|
||||
"label": "Where",
|
||||
"configProperty": "actionConfiguration.formData.list.where.data",
|
||||
"nestedLevels": 3,
|
||||
"controlType": "WHERE_CLAUSE",
|
||||
"-subtitle": "Array of Objects",
|
||||
"-tooltipText": "Array of Objects",
|
||||
"-alternateViewTypes": ["json"],
|
||||
"logicalTypes": [
|
||||
{
|
||||
"label": "AND",
|
||||
"value": "AND"
|
||||
},
|
||||
{
|
||||
"label": "OR",
|
||||
"value": "OR"
|
||||
}
|
||||
],
|
||||
"comparisonTypes": [
|
||||
{
|
||||
"label": "==",
|
||||
"value": "EQ"
|
||||
},
|
||||
{
|
||||
"label": "!=",
|
||||
"value": "NOT_EQ"
|
||||
},
|
||||
{
|
||||
"label": "in",
|
||||
"value": "IN"
|
||||
},
|
||||
{
|
||||
"label": "not in",
|
||||
"value": "NOT_IN"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"controlType": "SECTION",
|
||||
"label": "Options",
|
||||
"controlType": "DOUBLE_COLUMN_ZONE",
|
||||
"children": [
|
||||
{
|
||||
"label": "Generate signed URL",
|
||||
|
|
@ -122,9 +76,52 @@
|
|||
"value": "NO"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"controlType": "SINGLE_COLUMN_ZONE",
|
||||
"description": "Optional",
|
||||
"children": [
|
||||
{
|
||||
"label": "Filter data",
|
||||
"configProperty": "actionConfiguration.formData.list.where.data",
|
||||
"nestedLevels": 3,
|
||||
"controlType": "WHERE_CLAUSE",
|
||||
"-subtitle": "Array of Objects",
|
||||
"-tooltipText": "Array of Objects",
|
||||
"-alternateViewTypes": ["json"],
|
||||
"logicalTypes": [
|
||||
{
|
||||
"label": "AND",
|
||||
"value": "AND"
|
||||
},
|
||||
{
|
||||
"label": "OR",
|
||||
"value": "OR"
|
||||
}
|
||||
],
|
||||
"comparisonTypes": [
|
||||
{
|
||||
"label": "==",
|
||||
"value": "EQ"
|
||||
},
|
||||
{
|
||||
"label": "!=",
|
||||
"value": "NOT_EQ"
|
||||
},
|
||||
{
|
||||
"label": "in",
|
||||
"value": "IN"
|
||||
},
|
||||
{
|
||||
"label": "not in",
|
||||
"value": "NOT_IN"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Sort By",
|
||||
"label": "Sort data",
|
||||
"configProperty": "actionConfiguration.formData.list.sortBy.data",
|
||||
"controlType": "SORTING",
|
||||
"-subtitle": "Array of Objects",
|
||||
|
|
@ -132,7 +129,7 @@
|
|||
"-alternateViewTypes": ["json"]
|
||||
},
|
||||
{
|
||||
"label": "Paginate By",
|
||||
"label": "Paginate data",
|
||||
"configProperty": "actionConfiguration.formData.list.pagination.data",
|
||||
"controlType": "PAGINATION",
|
||||
"-subtitle": "Object",
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
{
|
||||
"identifier": "READ_FILE",
|
||||
"controlType": "SECTION",
|
||||
"controlType": "SECTION_V2",
|
||||
"conditionals": {
|
||||
"show": "{{actionConfiguration.formData.command.data === 'READ_FILE'}}"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"controlType": "SECTION",
|
||||
"label": "Select bucket to query",
|
||||
"controlType": "DOUBLE_COLUMN_ZONE",
|
||||
"children": [
|
||||
{
|
||||
"label": "Bucket name",
|
||||
|
|
@ -20,8 +19,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"controlType": "SECTION",
|
||||
"label": "Query",
|
||||
"controlType": "DOUBLE_COLUMN_ZONE",
|
||||
"description": "Optional",
|
||||
"children": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,39 +1,44 @@
|
|||
{
|
||||
"editor": [
|
||||
{
|
||||
"controlType": "SECTION",
|
||||
"controlType": "SECTION_V2",
|
||||
"identifier": "SELECTOR",
|
||||
"children": [
|
||||
{
|
||||
"label": "Command",
|
||||
"description": "Choose the method you would like to use",
|
||||
"configProperty": "actionConfiguration.formData.command.data",
|
||||
"controlType": "DROP_DOWN",
|
||||
"initialValue": "LIST",
|
||||
"options": [
|
||||
"controlType": "DOUBLE_COLUMN_ZONE",
|
||||
"children": [
|
||||
{
|
||||
"label": "List files in bucket",
|
||||
"value": "LIST"
|
||||
},
|
||||
{
|
||||
"label": "Create a new file",
|
||||
"value": "UPLOAD_FILE_FROM_BODY"
|
||||
},
|
||||
{
|
||||
"label": "Create multiple new files",
|
||||
"value": "UPLOAD_MULTIPLE_FILES_FROM_BODY"
|
||||
},
|
||||
{
|
||||
"label": "Read file",
|
||||
"value": "READ_FILE"
|
||||
},
|
||||
{
|
||||
"label": "Delete file",
|
||||
"value": "DELETE_FILE"
|
||||
},
|
||||
{
|
||||
"label": "Delete multiple files",
|
||||
"value": "DELETE_MULTIPLE_FILES"
|
||||
"label": "Command",
|
||||
"description": "Choose the method you would like to use",
|
||||
"configProperty": "actionConfiguration.formData.command.data",
|
||||
"controlType": "DROP_DOWN",
|
||||
"initialValue": "LIST",
|
||||
"options": [
|
||||
{
|
||||
"label": "List files in bucket",
|
||||
"value": "LIST"
|
||||
},
|
||||
{
|
||||
"label": "Create a new file",
|
||||
"value": "UPLOAD_FILE_FROM_BODY"
|
||||
},
|
||||
{
|
||||
"label": "Create multiple new files",
|
||||
"value": "UPLOAD_MULTIPLE_FILES_FROM_BODY"
|
||||
},
|
||||
{
|
||||
"label": "Read file",
|
||||
"value": "READ_FILE"
|
||||
},
|
||||
{
|
||||
"label": "Delete file",
|
||||
"value": "DELETE_FILE"
|
||||
},
|
||||
{
|
||||
"label": "Delete multiple files",
|
||||
"value": "DELETE_MULTIPLE_FILES"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user