this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

complete CRC cards as training post

+23 -129
+23 -129
src/pages/posts/crc-cards-as-training-material.mdx
··· 11 11 12 12 [CRC Cards](https://en.wikipedia.org/wiki/Class-responsibility-collaboration_card) are a teaching tool on how to design software. They were proposed by Kent Beck and Ward Cunningham, and, hell yeah it's useful. 13 13 14 + <CrcCard name="Component name" responsabilities={["First responsability", "second responsability"]} collaborators={["First collaborator", "second collaborator"]} /> 15 + 14 16 When I'm talking with tech leaders, my goal is to sharpen our vision about the software we are working on. When developers implemente features, I often see responsability leaks: the feature works, but the component are hard to read, hard to reuse and we pile up technical debt too quickly. 15 17 16 18 CRC cards are a great tool to focus the discussion and to aknowledge the fact that the developer shared her global vision to each individual local component who must rely only on its local scope. Let's take an example of one discussion. ··· 19 21 20 22 Disclaimer: we're about to look at a very ugly code that is definetely doing too many things. The purpose of the discussion I have is to show to the tech lead that we really want to prevent this to happen and it is her mission to standardize it with her team. 21 23 22 - Let's say we have a `UserBookmarks` component. Its role is to display a list of bookmarks the user saved. 24 + Let's say we have a `UserBookmarks` component. 23 25 24 26 ```tsx 25 27 interface Props { ··· 60 62 setIsLoading(false) 61 63 } 62 64 } 65 + 66 + const tilesAnimation = gsap.to({ 67 + duration: 0.8, 68 + opacity: 0.35, 69 + yoyo: true, 70 + repeat: -1, 71 + stagger: 0.025, 72 + }) 63 73 64 74 return <div className="user-bookmarks"> 65 75 <Title title={strings['frontoffice.bookmark.user_bookmarks']} /> 66 - {toolList} 76 + {isLoading 77 + ? <TilesSkeleton animation={tilesAnimation} numberOfTiles={16} /> 78 + : <BookmarkItem 79 + key={bookmark.id} 80 + data={bookmark} 81 + />} 67 82 68 83 <PrimaryButton 69 84 text={strings['frontoffice.bookmark.all_bookmarks']} ··· 75 90 <AddBookmarkModal 76 91 visible={showAddBookmarkModal} 77 92 onClose={() => setShowAddBookmarkModal(false)} 78 - tools={availableCustomTools} 93 + bookmarks={bookmarks} 79 94 onBookmarkAdd={addBookmarkToUser} 80 95 /> 81 96 </div> 82 97 } 83 - 84 98 ``` 85 99 86 - ```tsx 87 - import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 88 - import { gsap } from 'gsap'; 89 - import differenceBy from 'lodash/differenceBy'; 90 - import React, { useCallback, useEffect, useState } from 'react'; 91 - 92 - import { PrimaryButton } from 'components/CustomButton/CustomButton'; 93 - import strings from 'components/Localization/Localisation'; 94 - import { Title } from 'components/Title/Title'; 95 - import { useLanguageContext } from 'context/LanguageContext'; 96 - import { 97 - addToolToUser, 98 - fetchToolsForUser, 99 - removeToolFromUser, 100 - } from 'data/actions/ToolActions'; 101 - import { CodeIso } from 'types/Language'; 102 - import { Tool } from 'types/Tool'; 103 - import { Tools } from 'types/Tools'; 104 - import { Ui } from 'types/Ui'; 105 - import { User } from 'types/User'; 106 - 107 - import AddToolModal from './AddToolModal/AddToolModal'; 108 - import { TilesSkeleton } from './TilesSkeleton'; 109 - import { ToolItem } from './Tool/ToolItem'; 110 - 111 - export const Toolbox: React.FC = ({ 112 - user, 113 - ui, 114 - customTools, 115 - userTools, 116 - indispensableTools, 117 - userIsUpdating, 118 - getToolData, 119 - addToolToUser, 120 - removeToolFromUser, 121 - }) => { 122 - const { language } = useLanguageContext(); 123 - 124 - const [showAddToolModal, setShowAddToolModal] = useState(false); 125 - const [showDeleteTool, setShowDeleteTool] = useState(false); 126 - 127 - const [tileAnimation, setTileAnimation] = useState<GSAPTween>(); 128 - const [fakeTiles, setFakeTiles] = useState<unknown[]>([]); 129 - 130 - const [toolList, setToolList] = useState<JSX.Element>(); 131 - 132 - const userId = user['@id']; 133 - const uiLoading = ui.loading; 134 - 135 - const availableCustomTools = differenceBy(customTools, userTools, '@id'); 136 - 137 - const startLoadAnimation = (): void => { 138 - setTileAnimation( 139 - gsap.to(fakeTiles, { 140 - duration: 0.8, 141 - opacity: 0.35, 142 - yoyo: true, 143 - repeat: -1, 144 - stagger: 0.025, 145 - }), 146 - ); 147 - }; 148 - 149 - const stopLoadingAnimation = useCallback((): void => { 150 - tileAnimation?.kill(); 151 - }, [tileAnimation]); 152 - 153 - const addBookmark = (): void => { 154 - setShowAddToolModal(true); 155 - setShowDeleteTool(false); 156 - }; 157 - 158 - useEffect(() => { 159 - startLoadAnimation(); 160 - if (userId) { 161 - getToolData(user, language); 162 - } 163 - }, [userId, language]); 164 - 165 - useEffect(() => { 166 - if (!uiLoading) { 167 - stopLoadingAnimation(); 168 - setToolList( 169 - <div className="tool-list"> 170 - {indispensableTools.map(tool => ( 171 - <ToolItem key={tool['@id']} data={tool} showDeleteButton={false} /> 172 - ))} 173 - 174 - {userTools.map(tool => ( 175 - <ToolItem 176 - key={tool['@id']} 177 - data={tool} 178 - showDeleteButton={showDeleteTool} 179 - onDelete={() => removeToolFromUser(tool)} 180 - /> 181 - ))} 100 + It's a reeeeeeally long component that does many things, (FYI it is a simplified version of a component in one of my project). Most of the time, the tech lead freezes seeing how many things we need to talk to. Let's break it down piece by piece. 182 101 183 - </div>, 184 - ); 185 - } else { 186 - setToolList(<TilesSkeleton setFakeTiles={setFakeTiles} numberOfTiles={16} />); 187 - } 188 - }, [uiLoading]); 102 + ## Inputs and output 189 103 190 - return ( 191 - <div className="Toolbox"> 192 - <Title title={strings['frontoffice.toolbox.my_tools']} /> 193 - {toolList} 104 + The `UserBookmarks` component takes a `user` prop and return a list of styled bookmarks with the possibility to add bookmark via a modal. 194 105 195 - <PrimaryButton 196 - text={strings['frontoffice.toolbox.all_apps']} 197 - onClick={addBookmark} 198 - alt={'see all apps button'} 199 - image={<FontAwesomeIcon icon={['fas', 'arrow-right']} color="white" />} 200 - positionOfImage="right" 201 - disabled={true} 202 - /> 106 + Cool! That's the first thing we can note on our CRC card. 203 107 204 - <AddToolModal 205 - visible={showAddToolModal} 206 - onClose={() => setShowAddToolModal(false)} 207 - tools={availableCustomTools} 208 - onToolAdd={addToolToUser} 209 - userIsUpdating={userIsUpdating} 210 - /> 211 - </div> 212 - ); 213 - }; 214 - ``` 108 + <CrcCard name="UserBookmarks" responsabilities={["Display user bookmarks"]} collaborators={["Home.tsx"]} />