Ops Notes Component Library
Introduction
Notes component built with React using Fabric, and styled-components.
Props
Name | Type | Required | Default | Description |
---|
notes | Object | Yes | | Notes object containing all notes |
handleNewSubmit | Function | Yes | | Function that fires when submitting a new note. Takes in input string and selected Note type |
timeZone | string | No | moment.tz.guess() | Current timezone to correctly display timestamps through moment-timezone (by default will try to guess user's timezone based on browser) |
onOpen | Function | No | | Function that fires whenever the notes module is opened |
onClose | Function | No | | Function that fires whenever the notes module is closed |
loadingNotes | boolean | No | false | Pass true when loading notes and false when finished, for spinner |
title | string | No | '00000000' | Title for the header following the prefix |
titlePrefix | string | No | 'Lot#' | Prefix for the header |
searchTypeKey | string | No | 'lotNotes' | Default search key for searchbar dropdown. (Must match a key on the object passed to the notes prop) |
buttonText | string | No | 'Notes' | Text for the closed notes button |
keyboardShortcut | string | No | 'F6' | Keyboard key to open the notes modules |
bounds | string | No | 'body' | Restriction for the draggable area of the open notes module |
defaultPosition | Object | No | { x: 0, y: 0 } | Default x and y position of the open notes module when it is first opened |
autoSearch | boolean | No | true | Automatically search notes every time user types in searchbox rather than on search button click |
stickyHeader | boolean | No | true | Enable sticky headers for every note to help user maintain context on long notes |
defaultOpen | boolean | No | false | Whether or not notes are open by default on component load |
disableNewNote | boolean | No | false | Whether or not to show new note input |
translations | Object | No | | Translations for localization |
handleScrollEnd | Function | No | | Function to handle the end of scroll in notes |
onChangeNote | Function | No | | Function to handle change of note |
reverseList | boolean | No | true | Flag to determine if the list has to be reversed |
loadNextPage | boolean | No | false | Flag to determine if the next page list needs to be fetched |
disabled | boolean | No | false | Disables the note button |
dateTimeFormat | boolean | No | 'MMM Do [']YY h:mma z' | Change the format of the date and time (use moment supported formats: https://momentjs.com/docs/#/parsing/string-format/ ) |
notesTypes | Array | No | [] | An array of notes types (eg: [{ key: 'lotNotes', text: 'LOT NOTES' }, { key: 'titleNotes', text: 'TITLE NOTES' }]) that the consumer app has. Render's the spinner for the respective notes type if the data fetch is in progress. The loadingNotes prop (for global spinner) will be ignored if notesTypes is passed. |
Code Example
Component
import React from 'react'
import Notes from '@copart/notes-component'
import { exampleNotes } from './exampleNotes'
import exampleTranslationsMap from './exampleTranslationsMap'
class App extends React.Component {
state = {
id: '12345678',
notes: {},
loading: false,
}
onOpen = () => {
this.setState({ loading: true })
setTimeout(() => {
this.setState({ loading: false, notes: exampleNotes })
}, 1000)
}
onSubmit = (newNoteText) => {
const newNotes = { ...exampleNotes }
newNotes.lotNotes.data.push({
crt_dt: '2018-08-27T07:41:04.000Z',
crt_user: 'username',
note_desc: newNoteText,
})
this.setState({ loading: false, notes: newNotes })
}
render() {
const { notes, loading, id } = this.state
return (
<Notes
titlePrefix="ID#"
title={id}
notes={notes}
onOpen={this.onOpen}
handleNewSubmit={this.onSubmit}
loadingNotes={loading}
searchTypeKey="noteTypeKey2"
timeZone="Europe/Berlin"
translations={exampleTranslationsMap}
// dateTimeFormat={'MM/DD/YYYY HH:mm:ss z'}
// disabled={true}
/>
)
}
}
export default App
Notes Object Example
import { EXAMPLE_PATHS as examplePaths, EXAMPLE_FIELD_MAP as exampleFieldMap } from './examplePaths'
import exampleStages from './exampleStages'
export const exampleNotes = {
noteTypeKey1: {
display: 'NOTE TYPE 1',
format: 'table',
servicePaths: examplePaths,
stages: exampleStages,
fieldMap: exampleFieldMap,
data: [
{
crt_user: 'username1',
crt_dt: '2018-08-22T07:41:04.000Z',
json: {
previous_lot: {
field_1: 'value',
field_2: {
inner_prop_1: null,
inner_prop_2: 'abc',
},
field_3: 123,
},
current_lot: {
field_1: 'other_value',
field_2: {
inner_prop_1: null,
inner_prop_2: 'cba',
},
field_3: 321,
},
},
},
{
crt_user: 'username2',
crt_dt: '2018-08-23T07:41:04.000Z',
json: {
previous_lot: {
field_1: 'value',
},
current_lot: {
field_1: 'other_value',
},
},
},
],
},
noteTypeKey2: {
display: 'NOTE TYPE 2',
format: 'text',
enableAddNote: true,
data: [
{
crt_user: 'username1',
crt_dt: '2018-08-22T07:41:04.000Z',
notes: 'Note text 1',
},
{
crt_user: 'username2',
crt_dt: '2018-08-23T07:41:04.000Z',
notes: 'Note text 2',
},
],
},
noteTypeKey3: {
display: 'NOTE TYPE 3',
format: 'text',
data: [
{
crt_user: 'username1',
crt_dt: '2018-08-22T07:41:04.000Z',
note_desc: 'Note description text 1',
},
{
crt_user: 'username2',
crt_dt: '2018-08-23T07:41:04.000Z',
note_desc: 'Note description text 2',
},
],
},
}
Service Paths Example
export const EXAMPLE_PATHS = {
field_1: ['field_1'],
field_2: ['field_2', 'inner_prop_2'],
field_3: ['field_3'],
}
export const EXAMPLE_FIELD_MAP = {
field_1: 'field1',
field_2: 'field2',
field_3: 'field3',
}
Stages Example
const exampleStages = {
value: 'Readable value',
other_value: 'Other readable value',
}
export default exampleStages
Translations Map Example
const exampleTranslationsMap = {
field1: 'Field One',
field2: 'Field Two',
field3: 'Field Three',
}
Contributions
Contributions are welcome, create a Pull Request for any improvements/fixes.