Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed GET and DELETE request input renders and added all UX fixes #9498

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
161 changes: 123 additions & 38 deletions frontend/src/Editor/QueryManager/QueryEditors/Stripe.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { openapiService } from '@/_services';
import { CodeHinter } from '../../CodeBuilder/CodeHinter';
import { withTranslation } from 'react-i18next';
import { queryManagerSelectComponentStyle } from '@/_ui/Select/styles';
import { ToolTip } from '@/_components';

const operationColorMapping = {
get: 'azure',
Expand Down Expand Up @@ -35,7 +36,6 @@ class StripeComponent extends React.Component {
params: queryParams,
},
});

this.fetchOpenApiSpec();
}

Expand All @@ -62,8 +62,8 @@ class StripeComponent extends React.Component {
}

changeOperation = (value) => {
const operation = value.split(',')[0];
const path = value.split(',')[1];
const operation = value.split('/', 2)[0];
const path = value.substring(value.indexOf('/'));

this.setState(
{
Expand Down Expand Up @@ -116,7 +116,8 @@ class StripeComponent extends React.Component {

renderOperationOption = (props) => {
const path = props.value;
const operation = props.label;
const operation = props.operation;

if (path && operation) {
return (
<div className="row">
Expand All @@ -135,22 +136,44 @@ class StripeComponent extends React.Component {
};

computeOperationSelectionOptions = (operationOptions) => {
let options = [];
let pgs = []; // array of objects
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer const and better explanatory names. Keeping it as option/selectionOptions itself works?

const paths = operationOptions?.paths;

if (paths) {
for (const path of Object.keys(paths)) {
for (const operation of Object.keys(paths[path])) {
options.push({
value: `${operation},${path}`,
name: path,
operation: operation,
});
//path looks like get/v1/account/{id}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path will not have the http method info in it right?
GET /v1/account/{id}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

let interim = path.split('/')[2]; // gives category of path, here "account"
let found = pgs.findIndex((obj) => obj.label === interim); //returns index of object that has label key's value as interim

if (found >= 0) {
// object with label as interim exists in pgs
pgs[found]['options'].push({
value: `${operation}${path}`,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we appending operation here? 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will be better to revise to not use flags (like found here), but to show the actual intent of categorising in the code instead of comments. Wdyt?

  computeOperationSelectionOptions = (operationOptions) => {
    const paths = operationOptions.paths;
    if (isEmpty(paths)) return [];

    const selectionOptions = Object.keys(paths).reduce((acc, path) => {
      const operations = Object.keys(paths[path]);
      // the assumption is that there will always be /api/*, maybe we need a default category?
      const category = path.split('/')[2] || ' Default' ; 

      operations.forEach((operation) => {
        const option = {
          value: `${operation}${path}`,
          label: `${operation}${path}`,
          name: path,
          operation: operation,
        };

        const existingCategory = acc.find((obj) => obj.label === category);

        if (existingCategory) {
          existingCategory.options.push(option);
        } else {
          acc.push({
            label: category,
            options: [option],
          });
        }
      });

      return acc;
    }, []);

    return selectionOptions;
  };

label: `${operation}${path}`,
name: path,
operation: operation,
});
} else {
// object with label as interim does not exists in pgs
// creating new object in pgs with label as interim
pgs.push({
label: interim,
options: [
{
label: `${operation}${path}`,
value: `${operation}${path}`,
name: path,
operation: operation,
},
],
});
}
}
}
}

return options;
return pgs;
};

render() {
Expand All @@ -173,7 +196,10 @@ class StripeComponent extends React.Component {
}
}

const currentValue = this.state.options?.operation + ',' + this.props.options?.path ?? null;
const currentValue = {
operation: this.state.options?.operation,
value: this.state.options?.operation + this.state.options?.path,
};

return (
<div>
Expand Down Expand Up @@ -215,19 +241,36 @@ class StripeComponent extends React.Component {
{selectedOperation && (
<div className={`row stripe-fields-row ${this.props.darkMode && 'theme-dark'}`}>
{pathParams.length > 0 && (
<div className={`path-fields ${Object.keys(requestBody.schema.properties).length === 0 && 'd-none'}`}>
<h5 className="text-heading">{this.props.t('globals.path', 'PATH')}</h5>
<div className="input-group-parent-container">
<div className={`path-fields d-flex ${pathParams.length === 0 && 'd-none'}`}>
<h5 className="text-heading form-label">{this.props.t('globals.path', 'PATH')}</h5>
<div className="flex-grow-1 input-group-parent-container">
{pathParams.map((param) => (
<div className="input-group-wrapper" key={param.name}>
<div className="input-group">
<div className="col-auto field field-width-179">
<input
type="text"
value={param.name}
className="form-control border-0"
placeholder="key"
/>
<div className="col-auto d-flex field field-width-179 align-items-center">
{param?.description ? (
<ToolTip message={param.description}>
<u className="cursor-help">
<input
type="text"
value={param.name}
className="form-control"
placeholder="key"
disabled
/>
</u>
</ToolTip>
) : (
<input
type="text"
value={param.name}
className="form-control"
placeholder="key"
disabled
/>
)}
{param.required && <span className="text-danger fw-bold ">*</span>}
<div className="p-2 text-muted ">{param.schema?.type?.substring(0, 3).toUpperCase()}</div>
</div>
<div className="col field overflow-hidden">
<CodeHinter
Expand Down Expand Up @@ -266,24 +309,45 @@ class StripeComponent extends React.Component {
</div>
</div>
)}

{queryParams.length > 0 && (
<div
className={`query-fields ${Object.keys(requestBody.schema.properties).length === 0 && 'd-none'}`}
>
<h5 className="text-heading">{this.props.t('globals.query'.toUpperCase(), 'QUERY')}</h5>
<div className="input-group-parent-container">
<div className={`query-fields d-flex ${queryParams.length === 0 && 'd-none'}`}>
<h5 className="text-heading form-label">{this.props.t('globals.query'.toUpperCase(), 'Query')}</h5>
<div className="flex-grow-1 input-group-parent-container">
{queryParams.map((param) => (
<div className="input-group-wrapper" key={param.name}>
<div className="input-group">
<div className="col-auto field field-width-179">
<input
type="text"
value={param.name}
className="form-control"
placeholder="key"
disabled
/>
<div className="col-auto d-flex field field-width-179 align-items-center">
{param?.description ? (
<ToolTip message={param.description}>
<u className="cursor-help">
<input
type="text"
value={param.name}
className="form-control"
placeholder="key"
disabled
/>
</u>
</ToolTip>
) : (
<input
type="text"
value={param.name}
className="form-control"
placeholder="key"
disabled
/>
)}
{param.required && <span className="text-danger fw-bold">*</span>}
<div className="p-2 text-muted ">
{param?.schema?.anyOf
? param?.schema?.anyOf.map((type, i) =>
i < param.schema?.anyOf.length - 1
? type.type.substring(0, 3).toUpperCase() + '|'
: type.type.substring(0, 3).toUpperCase()
)
: param?.schema?.type?.substring(0, 3).toUpperCase()}
</div>
</div>
<div className="col field overflow-hidden">
<CodeHinter
Expand Down Expand Up @@ -338,9 +402,30 @@ class StripeComponent extends React.Component {
{Object.keys(requestBody.schema.properties).map((param) => (
<div className="input-group-wrapper" key={param.name}>
<div className="input-group">
<div className="col-auto field field-width-179">
<input type="text" value={param} className="form-control" placeholder="key" disabled />
<div className="col-auto d-flex field field-width-179 align-items-center">
{requestBody.schema.properties[param]?.['description'] ? (
<ToolTip
message={DOMPurify.sanitize(requestBody.schema.properties[param]['description'])}
>
<u className="cursor-help">
<input
type="text"
value={param}
className="form-control"
placeholder="key"
disabled
/>
</u>
</ToolTip>
) : (
<input type="text" value={param} className="form-control" placeholder="key" disabled />
)}
{param.required && <span className="text-danger fw-bold">*</span>}
<div className="p-2 text-muted ">
{requestBody?.schema?.properties?.[param]?.['type']?.substring(0, 3).toUpperCase()}
</div>
</div>

<div className="col field overflow-hidden">
<CodeHinter
initialValue={this.state.options.params?.request[param] ?? ''}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/_ui/Select/SelectComponent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const SelectComponent = ({

return option.label;
};

//console.log(value)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove comment

return (
<Select
{...restProps}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/_ui/Select/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export function queryManagerSelectComponentStyle(darkMode, width = 224, height =
backgroundColor: darkMode ? '' : '#F8FAFF',
borderColor: '#3E63DD',
boxShadow: '0px 0px 0px 2px #C6D4F9 ',
opacity: 0.5,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change will affect all selects in query manager. Is that expected?

},
cursor: 'pointer',
}),
Expand Down