STONEm Front-end Development Update: Wallet Manager Screen Refactor Fix.

in #utopian-io5 years ago (edited)

Repository

https://github.com/stonecoinproject/stonem-frontend

Pull Request

https://github.com/stonecoinproject/stonem-frontend/pull/49

Continuing with the development of the STONE masternodes web-client, our previous update added the masternodes manager screen alongside some very vital constructs and reusable architectural patterns.

However, for any software project to stay healthy, scale and remain relevant, smart and efficient practices must be adopted. The masternodes screen inadvertently added some poor code practices to the source base as evidenced in the CodeClimate report above.

The analytical report indicated the code contained as much as 3 code smells (poor practices) and 16 duplications. If not quickly and carefully tackled, these poor practices may quickly compound till you are staring down on a mountain of technical debt.

To tackle some of these issues, I got to work. I realized the 3 code smells detected were actually due to the unusually LOC (Lines of Code) length of methods contained in the wallet manager suite of components. To actively get this solved, I decided to split large functions into smaller functions so the below sample piece of code goes from this monumental entity:

const transactionItem:React.SFC<transactionItemProps> = ({
  amount,
  brand,
  children,
  date,
  hasNegativeIndex,
  title,
  time,
  ...props }) => (
  <ToggleProvider
    render={({
      isOn,
      doToggle,
    }) => (
    <Card
      border={2}
      borderColor={ isOn ? theme.colors.blue : theme.colors.bordergray}
      borderRadius={theme.radiusSizes[1]}
      p={3}
      onClick={doToggle}
      style={{
        cursor: 'pointer',
      }}
      {...props}
    >
      <Flex>
        <Box
          mr={3}
          width={1 / 5}
        >
          <Image width={1} src={brand} />
        </Box>

        <Box width={1}>
          <Box width={1}>
            <Flex width={1}>
              <CapsText
                fontSize={3}
                mb={3}
                width={1 / 2}
              >
                {title}
              </CapsText>

              <CapsText
                fontSize={3}
                mb={3}
                textAlign={'right'}
                width={1 / 2}
              >
                {time}
              </CapsText>
            </Flex>

            <Flex width={1}>
              <CapsText
                color={hasNegativeIndex ? 'red' : 'placeholdergray'}
                fontSize={3}
                mb={2}
                width={1 / 2}
              >
                {amount}
              </CapsText>

              <CapsText
                color={'placeholdergray'}
                fontSize={3}
                mb={2}
                textAlign={'right'}
                width={1 / 2}
              >
                {date}
              </CapsText>
            </Flex>
          </Box>
        </Box>
      </Flex>

      <Box style={{
        height: isOn ? 'auto' : '0',
        overflowY: 'hidden',
      }}>
        {children}
      </Box>
    </Card>
  )} />
);

...to the much more sane smaller function:

const transactionItem:React.SFC<transactionItemProps> = (props) => {
  return (
    <ToggleProvider
      render={({ isOn, doToggle }) => (
      <Card
        borderColor={ isOn ? theme.colors.blue : theme.colors.bordergray}
        onClick={doToggle}
        {...transactionItemCardStyles}
        {...props}
      >
        <Flex>
          {renderBrand(props.brand)}
          <Box width={1}>
            {renderHeading(props.title, props.time)}
            {renderMetaInformation(props.amount, props.date, props.hasNegativeIndex)}
          </Box>
        </Flex>

        <Box style={{
          height: isOn ? 'auto' : '0',
          overflowY: 'hidden',
        }}>{props.children}</Box>
      </Card>
    )} />
  );
};

With this strategy fully employed, I was able to eliminate all code smells reported by CodeClimate.

To take care of duplicates, I did a little research and realized a bulk of my code duplication came from writing code that iterates through an array and renders data from the array. This looked like a really good time to abstract this monotonous routine and I decided to employ Typescript generic React components that could be overloaded with props and use a custom renderer.

I created the src/generics directory and added the GenericList.tsxcomponent.

import * as React from 'react';

export interface GenericListProps<T> {
  /** Items to be members of the list. */
  items: T[];
  /** Callback method to render the items. Allows us delegate rendering for each consumer. */
  itemRenderer: (item: T, index: Number) => React.ReactNode;
}

/**
 * Generic class that serves as an abstraction for list item iterators.
 */
export default class GenericList<T> extends React.Component<GenericListProps<T>, {}> {
  constructor (props:GenericListProps<T>) {
    super(props);
  }

  render () {
    const {
      items,
      itemRenderer,
    } = this.props;

    return (items.map(itemRenderer));
  }
}

So running iterations now looks like this:

// Import the base generic list class

import { GenericList } from '../generics'

export class WalletTransactionItemList extends GenericList {}

Then in a consumer class.

// ...previous code

render () {
  return (
        <WalletTransactionItemList
          items={app.transactionData}
          itemRenderer={renderWalletManagerTransactionItem}
        />
  )
}

And this handles our iterations and iterables pretty well.

With all these implemented, we were able to get a clean slate from CodeClimate which feels pretty good. Pictured below is the code health analysis from Code Climate.

What's next?

  • Provide further code documentation for existing components.
  • Create responsive, mobile-first enhancements for the client.
  • Add authentication and coin node creation functionality.

Github Account

https://github.com/creatrixity

Sort:  

Thank you for your contribution. The post is of very high quality where you have explained it very nicely. This contribution adds significant value to the project since refactor is really needed whenever the project gets big, also the Wallet manager Screen looks great.

The code is of very high quality though as mentioned in the previous feedback you can try to remove hardcoded data from the code.


If you would like further explanation of the given score, then you can just ask.


Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Chat with us on Discord.

[utopian-moderator]

Thanks @codingdefined excellent review.

Thank you for your review, @codingdefined! Keep up the good work!

Hi @creatrixity!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Congratulations @creatrixity! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

You received more than 1000 as payout for your posts. Your next target is to reach a total payout of 2000

Click here to view your Board
If you no longer want to receive notifications, reply to this comment with the word STOP

To support your work, I also upvoted your post!

Support SteemitBoard's project! Vote for its witness and get one more award!

Hey, @creatrixity!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Coin Marketplace

STEEM 0.30
TRX 0.12
JST 0.033
BTC 64303.16
ETH 3137.29
USDT 1.00
SBD 3.97