diff options
Diffstat (limited to 'src/client/util/reportManager/ReportManagerComponents.tsx')
-rw-r--r-- | src/client/util/reportManager/ReportManagerComponents.tsx | 137 |
1 files changed, 119 insertions, 18 deletions
diff --git a/src/client/util/reportManager/ReportManagerComponents.tsx b/src/client/util/reportManager/ReportManagerComponents.tsx index 651442030..8f882c7f2 100644 --- a/src/client/util/reportManager/ReportManagerComponents.tsx +++ b/src/client/util/reportManager/ReportManagerComponents.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { Issue } from './reportManagerSchema'; -import { darkColors, getLabelColors, isLightText, lightColors } from './reportManagerUtils'; +import { darkColors, dashBlue, getLabelColors, isDarkMode, lightColors } from './reportManagerUtils'; import ReactMarkdown from 'react-markdown'; import rehypeRaw from 'rehype-raw'; import remarkGfm from 'remark-gfm'; @@ -8,9 +8,56 @@ import { StrCast } from '../../../fields/Types'; import { Doc } from '../../../fields/Doc'; /** - * Mini components to render issues. + * Mini helper components for the report component. */ +interface FilterProps<T> { + items: T[]; + activeValue: T | null; + setActiveValue: (val: T | null) => void; +} + +// filter ui for issues (horizontal list of tags) +export const Filter = <T extends string>({ items, activeValue, setActiveValue }: FilterProps<T>) => { + // establishing theme + const darkMode = isDarkMode(StrCast(Doc.UserDoc().userBackgroundColor)); + const colors = darkMode ? darkColors : lightColors; + const isTagDarkMode = isDarkMode(StrCast(Doc.UserDoc().userColor)); + const activeTagTextColor = isTagDarkMode ? darkColors.text : lightColors.text; + + return ( + <div className="issues-filter"> + <Tag + text={'All'} + onClick={() => { + setActiveValue(null); + }} + fontSize="12px" + backgroundColor={activeValue === null ? StrCast(Doc.UserDoc().userColor) : 'transparent'} + color={activeValue === null ? activeTagTextColor : colors.textGrey} + borderColor={activeValue === null ? StrCast(Doc.UserDoc().userColor) : colors.border} + border + /> + {items.map(item => { + return ( + <Tag + key={item} + text={item} + onClick={() => { + setActiveValue(item); + }} + fontSize="12px" + backgroundColor={activeValue === item ? StrCast(Doc.UserDoc().userColor) : 'transparent'} + color={activeValue === item ? activeTagTextColor : colors.textGrey} + border + borderColor={activeValue === item ? StrCast(Doc.UserDoc().userColor) : colors.border} + /> + ); + })} + </div> + ); +}; + interface IssueCardProps { issue: Issue; onSelect: () => void; @@ -19,11 +66,11 @@ interface IssueCardProps { // Component for the issue cards list on the left export const IssueCard = ({ issue, onSelect }: IssueCardProps) => { const [textColor, setTextColor] = React.useState(''); - const [bgColor, setBgColor] = React.useState(''); - const [borderColor, setBorderColor] = React.useState(''); + const [bgColor, setBgColor] = React.useState('transparent'); + const [borderColor, setBorderColor] = React.useState('transparent'); const resetColors = () => { - const darkMode = isLightText(StrCast(Doc.UserDoc().userBackgroundColor)); + const darkMode = isDarkMode(StrCast(Doc.UserDoc().userBackgroundColor)); const colors = darkMode ? darkColors : lightColors; setTextColor(colors.text); setBorderColor(colors.border); @@ -31,10 +78,10 @@ export const IssueCard = ({ issue, onSelect }: IssueCardProps) => { }; const handlePointerOver = () => { - const darkMode = isLightText(StrCast(Doc.UserDoc().userVariantColor)); + const darkMode = isDarkMode(StrCast(Doc.UserDoc().userColor)); setTextColor(darkMode ? darkColors.text : lightColors.text); - setBorderColor(StrCast(Doc.UserDoc().userVariantColor)); - setBgColor(StrCast(Doc.UserDoc().userVariantColor)); + setBorderColor(StrCast(Doc.UserDoc().userColor)); + setBgColor(StrCast(Doc.UserDoc().userColor)); }; React.useEffect(() => { @@ -165,10 +212,6 @@ export const IssueView = ({ issue }: IssueViewProps) => { const validPromise: Promise<boolean> = new Promise(resolve => { imgElement.addEventListener('load', () => resolve(true)); imgElement.addEventListener('error', () => resolve(false)); - // if taking too long to load, return prematurely (when the browndash server is down) - // setTimeout(() => { - // resolve(false); - // }, 1500); }); imgElement.src = src; return validPromise; @@ -180,9 +223,6 @@ export const IssueView = ({ issue }: IssueViewProps) => { const validPromise: Promise<boolean> = new Promise(resolve => { videoElement.addEventListener('loadeddata', () => resolve(true)); videoElement.addEventListener('error', () => resolve(false)); - // setTimeout(() => { - // resolve(false); - // }, 1500); }); videoElement.src = src; return validPromise; @@ -194,9 +234,6 @@ export const IssueView = ({ issue }: IssueViewProps) => { const validPromise: Promise<boolean> = new Promise(resolve => { audioElement.addEventListener('loadeddata', () => resolve(true)); audioElement.addEventListener('error', () => resolve(false)); - // setTimeout(() => { - // resolve(false); - // }, 1500); }); audioElement.src = src; return validPromise; @@ -257,3 +294,67 @@ export const Tag = ({ text, color, backgroundColor, fontSize, border, borderColo </div> ); }; + +interface FormInputProps { + value: string; + placeholder: string; + onChange: (val: string) => void; +} +export const FormInput = ({ value, placeholder, onChange }: FormInputProps) => { + const [inputBorderColor, setInputBorderColor] = React.useState(''); + + return ( + <input + className="report-input" + style={{ borderBottom: `1px solid ${inputBorderColor}` }} + value={value} + type="text" + placeholder={placeholder} + onChange={e => onChange(e.target.value)} + required + onPointerOver={() => { + if (inputBorderColor === dashBlue) return; + setInputBorderColor(isDarkMode(StrCast(Doc.UserDoc().userBackgroundColor)) ? darkColors.textGrey : lightColors.textGrey); + }} + onPointerOut={() => { + if (inputBorderColor === dashBlue) return; + setInputBorderColor(isDarkMode(StrCast(Doc.UserDoc().userBackgroundColor)) ? darkColors.border : lightColors.border); + }} + onFocus={() => { + setInputBorderColor(dashBlue); + }} + onBlur={() => { + setInputBorderColor(isDarkMode(StrCast(Doc.UserDoc().userBackgroundColor)) ? darkColors.border : lightColors.border); + }} + /> + ); +}; + +export const FormTextArea = ({ value, placeholder, onChange }: FormInputProps) => { + const [textAreaBorderColor, setTextAreaBorderColor] = React.useState(''); + + return ( + <textarea + className="report-textarea" + value={value} + placeholder={placeholder} + onChange={e => onChange(e.target.value)} + required + style={{ border: `1px solid ${textAreaBorderColor}` }} + onPointerOver={() => { + if (textAreaBorderColor === dashBlue) return; + setTextAreaBorderColor(isDarkMode(StrCast(Doc.UserDoc().userBackgroundColor)) ? darkColors.textGrey : lightColors.textGrey); + }} + onPointerOut={() => { + if (textAreaBorderColor === dashBlue) return; + setTextAreaBorderColor(isDarkMode(StrCast(Doc.UserDoc().userBackgroundColor)) ? darkColors.border : lightColors.border); + }} + onFocus={() => { + setTextAreaBorderColor(dashBlue); + }} + onBlur={() => { + setTextAreaBorderColor(isDarkMode(StrCast(Doc.UserDoc().userBackgroundColor)) ? darkColors.border : lightColors.border); + }} + /> + ); +}; |