Merge branch 'release'
This commit is contained in:
commit
bd11fdef91
|
|
@ -205,7 +205,16 @@
|
|||
"avatar_url": "https://avatars0.githubusercontent.com/u/25309929?v=4",
|
||||
"profile": "https://github.com/A-Scratchy",
|
||||
"contributions": [
|
||||
"code"
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "sumanthyedoti",
|
||||
"name": "Sumanth Yedoti",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/30371888?v=4",
|
||||
"profile": "https://github.com/sumanthyedoti",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -121,6 +121,9 @@ The Appsmith platform is available under the [Apache License 2.0](https://www.ap
|
|||
<td align="center"><a href="http://prashantchaubey.com"><img src="https://avatars3.githubusercontent.com/u/14848874?v=4" width="100px;" alt=""/><br /><sub><b>Prashant Chaubey</b></sub></a><br /><a href="https://github.com/appsmithorg/appsmith/commits?author=pc9795" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/A-Scratchy"><img src="https://avatars0.githubusercontent.com/u/25309929?v=4" width="100px;" alt=""/><br /><sub><b>Adam</b></sub></a><br /><a href="https://github.com/appsmithorg/appsmith/commits?author=A-Scratchy" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/sumanthyedoti"><img src="https://avatars3.githubusercontent.com/u/30371888?v=4" width="100px;" alt=""/><br /><sub><b>Sumanth Yedoti</b></sub></a><br /><a href="#tool-sumanthyedoti" title="Tools">🔧</a> <a href="https://github.com/appsmithorg/appsmith/commits?author=sumanthyedoti" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-enable -->
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
const dsl = require("../../../fixtures/inputdsl.json");
|
||||
const widgetsPage = require("../../../locators/Widgets.json");
|
||||
const dynamicInput = require("../../../locators/DynamicInput.json");
|
||||
|
||||
describe("Binding prompt", function() {
|
||||
before(() => {
|
||||
cy.addDsl(dsl);
|
||||
});
|
||||
|
||||
it("Show binding prompt when there are no bindings in the editor", () => {
|
||||
cy.openPropertyPane("inputwidget");
|
||||
cy.get(widgetsPage.defaultInput).type(" ");
|
||||
cy.get(dynamicInput.bindingPrompt).should("be.visible");
|
||||
|
||||
cy.get(widgetsPage.defaultInput).type("{{");
|
||||
cy.get(dynamicInput.bindingPrompt).should("not.be.visible");
|
||||
});
|
||||
});
|
||||
|
|
@ -48,6 +48,9 @@ describe("Video Widget Functionality", function() {
|
|||
|
||||
it("Update video url and check play and pause functionality validation", function() {
|
||||
cy.testCodeMirror(testdata.videoUrl);
|
||||
cy.get(".CodeMirror textarea")
|
||||
.first()
|
||||
.blur();
|
||||
cy.get(widgetsPage.autoPlay).click();
|
||||
cy.wait("@updateLayout").should(
|
||||
"have.nested.property",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"input": ".CodeMirror textarea",
|
||||
"hints": "ul.CodeMirror-hints",
|
||||
"evaluatedValue": ".t--CodeEditor-evaluatedValue"
|
||||
"evaluatedValue": ".t--CodeEditor-evaluatedValue",
|
||||
"bindingPrompt": ".t--no-binding-prompt"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
import React, { useRef } from "react";
|
||||
import styled from "styled-components";
|
||||
import { Colors } from "constants/Colors";
|
||||
|
||||
const Wrapper = styled.span<{ visible: boolean; bottomOffset: number }>`
|
||||
padding: 8px;
|
||||
font-size: 12px;
|
||||
color: ${Colors.GRAY_CHATEAU};
|
||||
border-radius: 2px;
|
||||
background-color: ${Colors.BLUE_CHARCOAL};
|
||||
position: absolute;
|
||||
bottom: ${props => -props.bottomOffset}px;
|
||||
width: 100%;
|
||||
line-height: 13px;
|
||||
visibility: ${props => (props.visible ? "visible" : "hidden")};
|
||||
z-index: 1;
|
||||
`;
|
||||
|
||||
const CurlyBraces = styled.span`
|
||||
color: white;
|
||||
background-color: #f3672a;
|
||||
border-radius: 2px;
|
||||
padding: 2px;
|
||||
margin: 0px 2px;
|
||||
`;
|
||||
|
||||
const BindingPrompt = (props: { isOpen: boolean }): JSX.Element => {
|
||||
const promptRef = useRef<HTMLDivElement>(null);
|
||||
let bottomOffset = 30;
|
||||
|
||||
if (promptRef.current) {
|
||||
const boundingRect = promptRef.current.getBoundingClientRect();
|
||||
bottomOffset = boundingRect.height;
|
||||
}
|
||||
|
||||
return (
|
||||
<Wrapper
|
||||
className="t--no-binding-prompt"
|
||||
ref={promptRef}
|
||||
visible={props.isOpen}
|
||||
bottomOffset={bottomOffset}
|
||||
>
|
||||
Type <CurlyBraces>{"{{"}</CurlyBraces> to see a list of variables
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default BindingPrompt;
|
||||
|
|
@ -36,6 +36,7 @@ import {
|
|||
import { bindingMarker } from "components/editorComponents/CodeEditor/markHelpers";
|
||||
import { bindingHint } from "components/editorComponents/CodeEditor/hintHelpers";
|
||||
import { retryPromise } from "utils/AppsmithUtils";
|
||||
import BindingPrompt from "./BindingPrompt";
|
||||
|
||||
const LightningMenu = lazy(() =>
|
||||
retryPromise(() => import("components/editorComponents/LightningMenu")),
|
||||
|
|
@ -91,9 +92,7 @@ class CodeEditor extends Component<Props, State> {
|
|||
};
|
||||
|
||||
textArea = React.createRef<HTMLTextAreaElement>();
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
||||
// @ts-ignore
|
||||
editor: CodeMirror.Editor;
|
||||
editor!: CodeMirror.Editor;
|
||||
hinters: Hinter[] = [];
|
||||
|
||||
constructor(props: Props) {
|
||||
|
|
@ -272,6 +271,7 @@ class CodeEditor extends Component<Props, State> {
|
|||
theme,
|
||||
disabled,
|
||||
className,
|
||||
placeholder,
|
||||
showLightningMenu,
|
||||
dataTreePath,
|
||||
dynamicData,
|
||||
|
|
@ -291,6 +291,10 @@ class CodeEditor extends Component<Props, State> {
|
|||
("evaluatedValue" in this.props ||
|
||||
("dataTreePath" in this.props && !!this.props.dataTreePath));
|
||||
|
||||
const showBindingPrompt =
|
||||
(!this.props.input.value?.includes("{{") || !this.props.input.value) &&
|
||||
showEvaluatedValue;
|
||||
|
||||
return (
|
||||
<DynamicAutocompleteInputWrapper
|
||||
theme={this.props.theme}
|
||||
|
|
@ -346,12 +350,11 @@ class CodeEditor extends Component<Props, State> {
|
|||
className="leftImageStyles"
|
||||
/>
|
||||
)}
|
||||
|
||||
<textarea
|
||||
ref={this.textArea}
|
||||
{..._.omit(this.props.input, ["onChange", "value"])}
|
||||
defaultValue={input.value}
|
||||
placeholder={this.props.placeholder}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
{this.props.link && (
|
||||
<React.Fragment>
|
||||
|
|
@ -368,6 +371,7 @@ class CodeEditor extends Component<Props, State> {
|
|||
{this.props.rightIcon && (
|
||||
<IconContainer>{this.props.rightIcon}</IconContainer>
|
||||
)}
|
||||
<BindingPrompt isOpen={showBindingPrompt} />
|
||||
</EditorWrapper>
|
||||
</EvaluatedValuePopup>
|
||||
</DynamicAutocompleteInputWrapper>
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ export const EditorWrapper = styled.div<{
|
|||
left: 0;
|
||||
top: 0;
|
||||
`
|
||||
: `z-index: 0; position: relative;`}
|
||||
: `position: relative;`}
|
||||
min-height: 32px;
|
||||
height: ${props => props.height || "auto"};
|
||||
background-color: ${props =>
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@ export default styled.div`
|
|||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
min-height: 50px;
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ const mapStateToProps = (
|
|||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch: Function): ReduxDispatchProps => ({
|
||||
const mapDispatchToProps = (dispatch: any): ReduxDispatchProps => ({
|
||||
updateDatasource: datasource =>
|
||||
dispatch(change(API_EDITOR_FORM_NAME, "datasource", datasource)),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
|
|||
selectionType: VALIDATION_TYPES.TEXT,
|
||||
isRequired: VALIDATION_TYPES.BOOLEAN,
|
||||
// onOptionChange: VALIDATION_TYPES.ACTION_SELECTOR,
|
||||
selectedOptionValueArr: VALIDATION_TYPES.ARRAY,
|
||||
selectedOptionValues: VALIDATION_TYPES.ARRAY,
|
||||
defaultOptionValue: VALIDATION_TYPES.DEFAULT_OPTION_VALUE,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ const withMeta = (WrappedWidget: typeof BaseWidget) => {
|
|||
Object.keys(metaProperties).forEach(metaProperty => {
|
||||
const defaultProperty = defaultProperties[metaProperty];
|
||||
if (
|
||||
prevProps[metaProperty] !== this.props[metaProperty] &&
|
||||
this.props[defaultProperty] === this.props[metaProperty]
|
||||
!_.isEqual(prevProps[metaProperty], this.props[metaProperty]) &&
|
||||
_.isEqual(this.props[defaultProperty], this.props[metaProperty])
|
||||
) {
|
||||
this.setState({ [metaProperty]: this.props[metaProperty] });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,6 +88,9 @@ public class DatabaseChangelog {
|
|||
* from an index with the fields `"organizationId", "name"`. If an index exists with the first ordering and we try
|
||||
* to **ensure** an index with the same name but the second ordering of fields, errors will show up and bad things
|
||||
* WILL happen.
|
||||
*
|
||||
* Also, please check out the following blog on how to best create indexes :
|
||||
* https://emptysqua.re/blog/optimizing-mongodb-compound-indexes/
|
||||
*/
|
||||
private static Index makeIndex(String... fields) {
|
||||
if (fields.length == 1) {
|
||||
|
|
@ -1193,4 +1196,23 @@ public class DatabaseChangelog {
|
|||
|
||||
}
|
||||
|
||||
@ChangeSet(order = "040", id = "new-page-new-action-add-indexes", author = "")
|
||||
public void addNewPageAndNewActionNewIndexes(MongoTemplate mongoTemplate) {
|
||||
|
||||
dropIndexIfExists(mongoTemplate, NewAction.class, "createdAt");
|
||||
|
||||
ensureIndexes(mongoTemplate, NewAction.class,
|
||||
makeIndex("applicationId", "deleted", "createdAt")
|
||||
.named("applicationId_deleted_createdAt_compound_index")
|
||||
);
|
||||
|
||||
dropIndexIfExists(mongoTemplate, NewPage.class, "createdAt");
|
||||
|
||||
ensureIndexes(mongoTemplate, NewPage.class,
|
||||
makeIndex("applicationId", "deleted")
|
||||
.named("applicationId_deleted_compound_index")
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import com.appsmith.server.domains.NewPage;
|
|||
import com.appsmith.server.domains.Page;
|
||||
import com.appsmith.server.domains.Plugin;
|
||||
import com.appsmith.server.domains.PluginType;
|
||||
import com.appsmith.server.domains.QNewAction;
|
||||
import com.appsmith.server.dtos.ActionDTO;
|
||||
import com.appsmith.server.dtos.ActionViewDTO;
|
||||
import com.appsmith.server.dtos.ExecuteActionDTO;
|
||||
|
|
@ -66,7 +65,6 @@ import static com.appsmith.server.acl.AclPermission.MANAGE_DATASOURCES;
|
|||
import static com.appsmith.server.acl.AclPermission.READ_ACTIONS;
|
||||
import static com.appsmith.server.acl.AclPermission.READ_PAGES;
|
||||
import static com.appsmith.server.helpers.BeanCopyUtils.copyNewFieldValuesIntoOldObject;
|
||||
import static com.appsmith.server.repositories.BaseAppsmithRepositoryImpl.fieldName;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
|
||||
@Service
|
||||
|
|
@ -727,14 +725,14 @@ public class NewActionServiceImpl extends BaseService<NewActionRepository, NewAc
|
|||
|
||||
@Override
|
||||
public Flux<ActionViewDTO> getActionsForViewMode(String applicationId) {
|
||||
Sort sort = Sort.by(fieldName(QNewAction.newAction.publishedAction) + "." + fieldName(QNewAction.newAction.publishedAction.name));
|
||||
|
||||
if (applicationId == null || applicationId.isEmpty()) {
|
||||
return Flux.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.APPLICATION_ID));
|
||||
}
|
||||
|
||||
// fetch the published actions by applicationId
|
||||
return findAllByApplicationIdAndViewMode(applicationId, true, EXECUTE_ACTIONS, sort)
|
||||
// No need to sort the results
|
||||
return findAllByApplicationIdAndViewMode(applicationId, true, EXECUTE_ACTIONS, null)
|
||||
.map(action -> {
|
||||
ActionViewDTO actionViewDTO = new ActionViewDTO();
|
||||
actionViewDTO.setId(action.getId());
|
||||
|
|
@ -783,7 +781,9 @@ public class NewActionServiceImpl extends BaseService<NewActionRepository, NewAc
|
|||
public Flux<ActionDTO> getUnpublishedActions(MultiValueMap<String, String> params) {
|
||||
String name = null;
|
||||
List<String> pageIds = new ArrayList<>();
|
||||
Sort sort = Sort.by(FieldName.NAME);
|
||||
|
||||
// In the edit mode, the actions should be displayed in the order they were created.
|
||||
Sort sort = Sort.by(FieldName.CREATED_AT);
|
||||
|
||||
if (params.getFirst(FieldName.NAME) != null) {
|
||||
name = params.getFirst(FieldName.NAME);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user