mirror of
https://github.com/Kong/insomnia
synced 2024-11-08 06:39:48 +00:00
Allow for renaming of a protofile (#2763)
This commit is contained in:
parent
b2bf1146f9
commit
f2737ff706
@ -0,0 +1,19 @@
|
||||
import { shouldSave } from '../editable';
|
||||
|
||||
describe('shouldSave', () => {
|
||||
it('should save if new and old are not the same', () => {
|
||||
expect(shouldSave('old', 'new')).toBe(true);
|
||||
});
|
||||
|
||||
it('should not save if new and old are the same', () => {
|
||||
expect(shouldSave('old', 'old')).toBe(false);
|
||||
});
|
||||
|
||||
it('should save if new is empty and we are not preventing blank', () => {
|
||||
expect(shouldSave('old', '', false)).toBe(true);
|
||||
});
|
||||
|
||||
it('should not save if new is empty and we are preventing blank', () => {
|
||||
expect(shouldSave('old', '', true)).toBe(false);
|
||||
});
|
||||
});
|
@ -3,6 +3,21 @@ import PropTypes from 'prop-types';
|
||||
import autobind from 'autobind-decorator';
|
||||
import KeydownBinder from '../keydown-binder';
|
||||
|
||||
export const shouldSave = (oldValue, newValue, preventBlank) => {
|
||||
// Should not save if length = 0 and we want to prevent blank
|
||||
if (preventBlank && !newValue.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Should not save if old value and new value is the same
|
||||
if (oldValue === newValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Should save
|
||||
return true;
|
||||
};
|
||||
|
||||
@autobind
|
||||
class Editable extends PureComponent {
|
||||
constructor(props) {
|
||||
@ -36,11 +51,12 @@ class Editable extends PureComponent {
|
||||
}
|
||||
|
||||
_handleEditEnd() {
|
||||
const value = this._input.value.trim();
|
||||
const originalValue = this.props.value;
|
||||
const newValue = this._input.value.trim();
|
||||
|
||||
if (value !== this.props.value) {
|
||||
// Don't run onSubmit for values that haven't been changed.
|
||||
this.props.onSubmit(value);
|
||||
if (shouldSave(originalValue, newValue, this.props.preventBlank)) {
|
||||
// Don't run onSubmit for values that haven't been changed
|
||||
this.props.onSubmit(newValue);
|
||||
}
|
||||
|
||||
// This timeout prevents the UI from showing the old value after submit.
|
||||
@ -73,6 +89,7 @@ class Editable extends PureComponent {
|
||||
blankValue,
|
||||
singleClick,
|
||||
onEditStart, // eslint-disable-line no-unused-vars
|
||||
preventBlank, // eslint-disable-line no-unused-vars
|
||||
className,
|
||||
renderReadView,
|
||||
...extra
|
||||
@ -124,6 +141,7 @@ Editable.propTypes = {
|
||||
singleClick: PropTypes.bool,
|
||||
onEditStart: PropTypes.func,
|
||||
className: PropTypes.string,
|
||||
preventBlank: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Editable;
|
||||
|
@ -100,6 +100,11 @@ class ProtoFilesModal extends React.PureComponent<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
async _handleRename(protoFile: ProtoFile, name: string): Promise<void> {
|
||||
await models.protoFile.update(protoFile, { name });
|
||||
await this._refresh();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { protoFiles, selectedProtoFileId } = this.state;
|
||||
|
||||
@ -122,6 +127,7 @@ class ProtoFilesModal extends React.PureComponent<Props, State> {
|
||||
selectedId={selectedProtoFileId}
|
||||
handleSelect={this._handleSelect}
|
||||
handleDelete={this._handleDelete}
|
||||
handleRename={this._handleRename}
|
||||
/>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
|
@ -1,16 +1,22 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import type { ProtoFile } from '../../../models/proto-file';
|
||||
import PromptButton from '../base/prompt-button';
|
||||
import type { DeleteProtoFileHandler, SelectProtoFileHandler } from './proto-file-list';
|
||||
import type {
|
||||
DeleteProtoFileHandler,
|
||||
RenameProtoFileHandler,
|
||||
SelectProtoFileHandler,
|
||||
} from './proto-file-list';
|
||||
import { ListGroupItem } from '../../../../../insomnia-components';
|
||||
import Editable from '../base/editable';
|
||||
|
||||
type Props = {
|
||||
protoFile: ProtoFile,
|
||||
isSelected?: boolean,
|
||||
handleSelect: SelectProtoFileHandler,
|
||||
handleDelete: DeleteProtoFileHandler,
|
||||
handleRename: RenameProtoFileHandler,
|
||||
};
|
||||
|
||||
const SelectableListItem: React.PureComponent<{ isSelected?: boolean }> = styled(ListGroupItem)`
|
||||
@ -21,7 +27,13 @@ const SelectableListItem: React.PureComponent<{ isSelected?: boolean }> = styled
|
||||
background-color: ${({ isSelected }) => isSelected && 'var(--hl-sm) !important'};
|
||||
`;
|
||||
|
||||
const ProtoFileListItem = ({ protoFile, isSelected, handleSelect, handleDelete }: Props) => {
|
||||
const ProtoFileListItem = ({
|
||||
protoFile,
|
||||
isSelected,
|
||||
handleSelect,
|
||||
handleDelete,
|
||||
handleRename,
|
||||
}: Props) => {
|
||||
const { name, _id } = protoFile;
|
||||
|
||||
// Don't re-instantiate the callbacks if the dependencies have not changed
|
||||
@ -33,11 +45,17 @@ const ProtoFileListItem = ({ protoFile, isSelected, handleSelect, handleDelete }
|
||||
},
|
||||
[handleDelete, protoFile],
|
||||
);
|
||||
const handleRenameCallback = React.useCallback(
|
||||
async (newName: string) => {
|
||||
await handleRename(protoFile, newName);
|
||||
},
|
||||
[handleRename, protoFile],
|
||||
);
|
||||
|
||||
return (
|
||||
<SelectableListItem isSelected={isSelected} onClick={handleSelectCallback}>
|
||||
<div className="row-spaced">
|
||||
{name}
|
||||
<Editable onSubmit={handleRenameCallback} value={name} preventBlank />
|
||||
<PromptButton
|
||||
className="btn btn--super-compact btn--outlined"
|
||||
addIcon
|
||||
|
@ -1,20 +1,28 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import type { ProtoFile } from '../../../models/proto-file';
|
||||
import { ListGroup, ListGroupItem } from 'insomnia-components';
|
||||
import ProtoFileListItem from './proto-file-list-item';
|
||||
|
||||
export type SelectProtoFileHandler = (id: string) => void;
|
||||
export type DeleteProtoFileHandler = (protofile: ProtoFile) => Promise<void>;
|
||||
export type RenameProtoFileHandler = (protoFile: ProtoFile, name: string) => Promise<void>;
|
||||
|
||||
type Props = {
|
||||
protoFiles: Array<ProtoFile>,
|
||||
selectedId?: string,
|
||||
handleSelect: SelectProtoFileHandler,
|
||||
handleDelete: DeleteProtoFileHandler,
|
||||
handleRename: RenameProtoFileHandler,
|
||||
};
|
||||
|
||||
const ProtoFileList = ({ protoFiles, selectedId, handleSelect, handleDelete }: Props) => (
|
||||
const ProtoFileList = ({
|
||||
protoFiles,
|
||||
selectedId,
|
||||
handleSelect,
|
||||
handleDelete,
|
||||
handleRename,
|
||||
}: Props) => (
|
||||
<ListGroup>
|
||||
{!protoFiles.length && <ListGroupItem>No proto files exist for this workspace</ListGroupItem>}
|
||||
{protoFiles.map(p => (
|
||||
@ -24,6 +32,7 @@ const ProtoFileList = ({ protoFiles, selectedId, handleSelect, handleDelete }: P
|
||||
isSelected={p._id === selectedId}
|
||||
handleSelect={handleSelect}
|
||||
handleDelete={handleDelete}
|
||||
handleRename={handleRename}
|
||||
/>
|
||||
))}
|
||||
</ListGroup>
|
||||
|
Loading…
Reference in New Issue
Block a user