Skip to content

Commit

Permalink
Fix ListView and add plugin-react-hooks.
Browse files Browse the repository at this point in the history
  • Loading branch information
phulin committed Feb 1, 2020
1 parent 17832cd commit 4e28042
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 32 deletions.
1 change: 0 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ src/components/FoilOverlay.js
src/components/GroupModal.js
src/components/GroupModalContext.js
src/components/ImageFallback.js
src/components/ListView.js
src/components/LoadingButton.js
src/components/MassBuyButton.js
src/components/MulticoloredAnalysis.js
Expand Down
3 changes: 3 additions & 0 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ extends:
plugins:
- jest
- prettier
- react-hooks
settings:
import/resolver:
webpack:
Expand Down Expand Up @@ -40,6 +41,8 @@ rules:
react/no-unescaped-entities:
- error
- forbid: ['>', '"', '}']
react-hooks/rules-of-hooks: error
react-hooks/exhaustive-deps: error
overrides:
- files: ['src/**']
rules:
Expand Down
86 changes: 55 additions & 31 deletions src/components/ListView.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useCallback, useContext, useState, useEffect } from 'react';
import PropTypes from 'prop-types';

import { Form, Input } from 'reactstrap';

Expand Down Expand Up @@ -98,29 +99,29 @@ const ListViewRow = ({ card, versions, checked, onCheck, addAlert }) => {
const json = await response.json();
if (json.success === 'true') {
const oldCardID = card.cardID;
card = { ...card, ...updated };
updateCubeCard(card.index, card);
const newCard = { ...card, ...updated };
updateCubeCard(card.index, newCard);
if (updated.cardID !== oldCardID) {
// changed version
const getResponse = await fetch(`/cube/api/getcardfromid/${updated.cardID}`);
const getJson = await getResponse.json();
updateCubeCard(card.index, { ...card, details: getJson.card });
updateCubeCard(card.index, { ...newCard, details: getJson.card });
}
}
} catch (err) {
addAlert('danger', 'Failed to send update request.');
throw err;
}
},
[cubeID, card],
[cubeID, card, updateCubeCard, addAlert],
);

const addTag = useCallback(
async (tag) => {
const newTags = [...tags, tag];
setTags(newTags);
try {
await syncCard({ tags: newTags.map((tag) => tag.text) });
await syncCard({ tags: newTags.map((newTag) => newTag.text) });
} catch (err) {
setTags(tags);
}
Expand All @@ -129,11 +130,11 @@ const ListViewRow = ({ card, versions, checked, onCheck, addAlert }) => {
);

const deleteTag = useCallback(
async (tagIndex) => {
const newTags = tags.filter((tag, index) => index !== tagIndex);
async (deleteIndex) => {
const newTags = tags.filter((tag, tagIndex) => tagIndex !== deleteIndex);
setTags(newTags);
try {
await syncCard({ tags: newTags.map((tag) => tag.text) });
await syncCard({ tags: newTags.map((newTag) => newTag.text) });
} catch (err) {
setTags(tags);
}
Expand All @@ -148,7 +149,7 @@ const ListViewRow = ({ card, versions, checked, onCheck, addAlert }) => {
newTags.splice(newIndex, 0, tag);
setTags(newTags);
try {
await syncCard({ tags: newTags.map((tag) => tag.text) });
await syncCard({ tags: newTags.map((newTag) => newTag.text) });
} catch (err) {
setTags(tags);
}
Expand All @@ -170,16 +171,16 @@ const ListViewRow = ({ card, versions, checked, onCheck, addAlert }) => {

const handleChange = useCallback(
async (event) => {
const target = event.target;
const { target } = event;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
const { name, tagName } = target;

const updateF = (values) => ({
...values,
const updateF = (currentValues) => ({
...currentValues,
[name]: value,
});

if (target.tagName.toLowerCase() === 'select') {
if (tagName.toLowerCase() === 'select') {
try {
const updatedCard = {};
if (name === 'colors') {
Expand All @@ -204,14 +205,12 @@ const ListViewRow = ({ card, versions, checked, onCheck, addAlert }) => {

const handleBlur = useCallback(
async (event) => {
const target = event.target;
const name = target.name;
const value = target.value;
const { target } = event;
const { name, value, tagName } = target;

// <select>s handled in handleChange above.
if (target.tagName.toLowerCase() !== 'select') {
if (tagName.toLowerCase() !== 'select') {
try {
// TODO: Apply some kind of loading indicator to the element.
// Note: We can use this logic on all but the colors field, which is a select anyway so this path is irrelevant.
await syncCard({
[name]: value,
Expand Down Expand Up @@ -308,6 +307,25 @@ const ListViewRow = ({ card, versions, checked, onCheck, addAlert }) => {
);
};

ListViewRow.propTypes = {
card: PropTypes.shape({
index: PropTypes.number.isRequired,
cardID: PropTypes.string.isRequired,
colors: PropTypes.arrayOf(PropTypes.oneOf([...'WUBRG'])).isRequired,
tags: PropTypes.arrayOf(PropTypes.string).isRequired,
details: PropTypes.shape({
name: PropTypes.string.isRequired,
}).isRequired,
}).isRequired,
versions: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string.isRequired,
version: PropTypes.string.isRequired,
})).isRequired,
checked: PropTypes.bool.isRequired,
onCheck: PropTypes.func.isRequired,
addAlert: PropTypes.func.isRequired,
};

const ListView = ({ cards }) => {
const [versionDict, setVersionDict] = useState({});
const [checked, setChecked] = useState([]);
Expand All @@ -331,19 +349,19 @@ const ListView = ({ cards }) => {
},
});
if (!response.ok) {
return console.error(response);
console.error(response);
return;
}

const json = await response.json();
setVersionDict((versionDict) => ({ ...versionDict, ...json.dict }));
setVersionDict((current) => ({ ...current, ...json.dict }));
}
};
wrapper();
}, [cards, versionDict]);

const handleCheckAll = useCallback((event) => {
const target = event.target;
const value = target.checked;
const value = event.target.checked;

if (value) {
setChecked(cards.map(({ index }) => index));
Expand All @@ -352,13 +370,13 @@ const ListView = ({ cards }) => {
setChecked([]);
setGroupModalCards([]);
}
}, []);
}, [cards, setGroupModalCards]);

const handleCheck = useCallback(
(event) => {
const value = event.target.checked;
const index = parseInt(event.target.getAttribute('data-index'));
if (!isNaN(value)) {
const index = parseInt(event.target.getAttribute('data-index'), 10);
if (Number.isInteger(value)) {
let newChecked = checked;
if (value) {
if (!newChecked.includes(index)) {
Expand All @@ -368,16 +386,16 @@ const ListView = ({ cards }) => {
newChecked = checked.filter((testIndex) => testIndex !== index);
}
setChecked(newChecked);
setGroupModalCards(newChecked.map((index) => cards.find((card) => card.index === index)).filter((x) => x));
setGroupModalCards(newChecked.map((cardIndex) => cards.find((card) => card.index === cardIndex)).filter((x) => x));
}
},
[checked],
[checked, cards, setGroupModalCards],
);

const sorted = sortDeep(cards, primary, secondary);

const rows = sorted.map(([label1, group1]) =>
group1.map(([label2, group2]) =>
const rows = sorted.map(([, group1]) =>
group1.map(([, group2]) =>
group2.map((card) => (
<ListViewRow
key={card._id}
Expand All @@ -391,7 +409,7 @@ const ListView = ({ cards }) => {
),
);

const rowsFlat = [].concat.apply([], [].concat.apply([], rows));
const rowsFlat = [].concat(...[].concat(...rows));

return (
<>
Expand Down Expand Up @@ -419,4 +437,10 @@ const ListView = ({ cards }) => {
);
};

ListView.propTypes = {
cards: PropTypes.arrayOf(PropTypes.shape({
_id: PropTypes.string.isRequired,
})).isRequired,
};

export default ListView;

0 comments on commit 4e28042

Please sign in to comment.