insomnia/packages/insomnia-app/app/ui/components/cookie-list.tsx
Dimitri Mitropoulos 42341e6e6e
fixes 'previewHidden' of undefined error (#3409)
* readability improvements and reduced indirection

* adds type for handleShowModifyCookieModal

* correctly types wrapperProps property, thereby fixing bug.

if you add `console.log({ previewHidden, propsOne: this.props.wrapperProps.activeWorkspaceMeta });` to the third line of `_renderPreview()` you'll see that `activeWorkspaceMeta` is indeed, sometimes, `undefined.

Also, there's no reason to use `await` on `this.setState`.  I didn't find any more of these in the codebase, I just found this one.

* adds type for swaggerUiSpec

* undoes lifting props to state

almost always, this is done for performance reasons, but I removed it the app is working pretty quick-and-snappy for me without needing to introduced duplicated application state and keep track of it.

I went ahead and measured it before and after this commit (using performance.now):

before = [
  1.93500000750646,
  1.149999996414408,
  0.9499999869149178,
  0.9950000094249845,
  0.8650000090710819,
  1.560000004246831,
  1.5699999930802733,
  0.8450000023003668,
  1.4550000196322799,
  1.3299999991431832,
  1.3050000125076622,
  1.4099999971222132,
  1.3099999923724681,
  1.3100000214762986,
  1.1999999987892807,
  1.0099999781232327,
  0.830000004498288,
  1.2449999921955168,
  1.2500000011641532,
  1.4349999837577343,
]

after = [
  2.9400000057648867,
  2.449999999953434,
  2.33499999740161,
  2.2849999950267375,
  1.7700000025797635,
  1.8149999959859997,
  2.1249999990686774,
  1.9150000007357448,
  2.074999996693805,
  1.9899999897461385,
  2.0200000144541264,
  2.869999996619299,
  2.1450000058393925,
  2.33499999740161,
  2.130000008037314,
  2.119999990100041,
  2.144999976735562,
  2.130000008037314,
  2.380000009201467,
  2.8999999922234565,
]

> R.mean(before)
> 1.2480000004870817

> R.mean(after)
> 2.243749999080319

> R.median(before)
> 1.2775000068359077

> R.median(after)
> 2.137499992386438

So basically, considering a 16ms render rate (i.e. 60hz), 1ms saved by lifting props to state makes no difference in application performance.

This is committed separately so that if there's any reason we want to keep the prior implementation, we can just still do so.
2021-05-24 10:14:00 -04:00

135 lines
4.6 KiB
TypeScript

import React, { PureComponent } from 'react';
import * as uuid from 'uuid';
import * as toughCookie from 'tough-cookie';
import { autoBindMethodsForReact } from 'class-autobind-decorator';
import { cookieToString } from 'insomnia-cookies';
import PromptButton from './base/prompt-button';
import RenderedText from './rendered-text';
import type { Cookie } from '../../models/cookie-jar';
import { Dropdown, DropdownButton, DropdownItem } from './base/dropdown/index';
import { AUTOBIND_CFG } from '../../common/constants';
import { HandleRender } from '../../common/render';
export interface CookieListProps {
handleCookieAdd: Function;
handleCookieDelete: Function;
handleDeleteAll: Function;
cookies: Cookie[];
newCookieDomainName: string;
handleShowModifyCookieModal: (cookie: Cookie) => void;
handleRender: HandleRender;
}
// Use tough-cookie MAX_DATE value
// https://github.com/salesforce/tough-cookie/blob/5ae97c6a28122f3fb309adcd8428274d9b2bd795/lib/cookie.js#L77
const MAX_TIME = 2147483647000;
@autoBindMethodsForReact(AUTOBIND_CFG)
class CookieList extends PureComponent<CookieListProps> {
_handleCookieAdd() {
const newCookie: Cookie = {
id: uuid.v4(),
key: 'foo',
value: 'bar',
domain: this.props.newCookieDomainName,
expires: MAX_TIME,
path: '/',
secure: false,
httpOnly: false,
};
this.props.handleCookieAdd(newCookie);
}
_handleDeleteCookie(cookie: Cookie) {
this.props.handleCookieDelete(cookie);
}
render() {
const { cookies, handleDeleteAll, handleShowModifyCookieModal, handleRender } = this.props;
return (
<div>
<table className="table--fancy cookie-table table--striped">
<thead>
<tr>
<th
style={{
minWidth: '10rem',
}}>
Domain
</th>
<th
style={{
width: '90%',
}}>
Cookie
</th>
<th
style={{
width: '2rem',
}}
className="text-right">
<Dropdown right>
<DropdownButton
title="Add cookie"
className="btn btn--super-duper-compact btn--outlined txt-md">
Actions <i className="fa fa-caret-down" />
</DropdownButton>
<DropdownItem onClick={this._handleCookieAdd}>
<i className="fa fa-plus-circle" /> Add Cookie
</DropdownItem>
<DropdownItem onClick={handleDeleteAll} buttonClass={PromptButton}>
<i className="fa fa-trash-o" /> Delete All
</DropdownItem>
</Dropdown>
</th>
</tr>
</thead>
<tbody key={cookies.length}>
{cookies.map((cookie, i) => {
const cookieString = cookieToString(toughCookie.Cookie.fromJSON(cookie));
return (
<tr className="selectable" key={i}>
<td>
<RenderedText render={handleRender}>{cookie.domain || ''}</RenderedText>
</td>
<td className="force-wrap wide">
<RenderedText render={handleRender}>{cookieString || ''}</RenderedText>
</td>
<td onClick={() => {}} className="text-right no-wrap">
<button
className="btn btn--super-compact btn--outlined"
onClick={() => { handleShowModifyCookieModal(cookie); }}
title="Edit cookie properties">
Edit
</button>{' '}
<PromptButton
className="btn btn--super-compact btn--outlined"
addIcon
confirmMessage=""
onClick={() => this._handleDeleteCookie(cookie)}
title="Delete cookie">
<i className="fa fa-trash-o" />
</PromptButton>
</td>
</tr>
);
})}
</tbody>
</table>
{cookies.length === 0 && (
<div className="pad faint italic text-center">
<p>I couldn't find any cookies for you.</p>
<p>
<button className="btn btn--clicky" onClick={() => this._handleCookieAdd()}>
Add Cookie <i className="fa fa-plus-circle" />
</button>
</p>
</div>
)}
</div>
);
}
}
export default CookieList;