diff --git a/client/src/components/ui/LongText/index.tsx b/client/src/components/ui/LongText/index.tsx index 31131f422ac55da5bc891fa68f926e0f2fe5e200..7a725f0fbf73d8d31496c86ad21e6ab0f79c300b 100644 --- a/client/src/components/ui/LongText/index.tsx +++ b/client/src/components/ui/LongText/index.tsx @@ -10,6 +10,11 @@ interface Props { open?: boolean; } +/** + * This component displays the given text property as a markdown string. The markdown will be + * compiled by the component and then displayed. If the text is long the text will be shown + * collapsed and allow the user to expand it and collapse it again. + */ export default function LongText({ text, open }: Props) { const [more, setMore] = useState(false); diff --git a/client/src/components/ui/LongText/markdown.ts b/client/src/components/ui/LongText/markdown.ts index f72628b3b83ec6735cad9ef4002b6facc1f2a07c..e4cba62c35529464bbc5d4cdd301c35241ac19e8 100644 --- a/client/src/components/ui/LongText/markdown.ts +++ b/client/src/components/ui/LongText/markdown.ts @@ -1,6 +1,15 @@ type TemplateValue = string | number | TemplateValue[]; +/** + * This is a simple helper function that will join the elements. This is to be used + * as a custom string template literal tag. The custom template tag is mainly used + * to get syntax highlighting in code editors. + * + * @param str The strings of the template + * @param values The values in the template + * @returns The concatenated string + */ function html(str: TemplateStringsArray, ...values: TemplateValue[]) { return str.map((s, i) => { const value = values[i]; @@ -23,6 +32,12 @@ interface Link { type LinkRegistry = Record<string, Footnote | Link>; +/** + * Escape the given string to be displayable directly inside of a HTML document. + * + * @param markdown The string to escape + * @returns The escaped string + */ function escapeHtml(markdown: string) { return markdown .replace(/"/g, html`"`) @@ -32,8 +47,15 @@ function escapeHtml(markdown: string) { .replace(/>/g, html`>`); } +/** + * Compile inline constructs of markdown that can be contained inside of a paragraph. + * + * @param markdown The source to compile + * @param data The data of all footnotes and named links in the source + * @returns The compiled output + */ function compileInlineConstructs(markdown: string, data: LinkRegistry): string { - let output = ''; + let output = ''; let offset = 0; let last_copy = 0; while (offset < markdown.length) { @@ -333,13 +355,28 @@ function compileInlineConstructs(markdown: string, data: LinkRegistry): string { return output; } -function linesToParagraph(lines: string[], paragraphs: string[], data: LinkRegistry) { - if (lines.length !== 0 && lines.join(' ').trim().length !== 0) { +/** + * Collect the given lines into a single paragraph, also compiling the inline constructs contained + * in the given lines. + * + * @param lines The lines to compile + * @param paragraphs Where to add the paragraphs to + * @param data The data of all footnotes and named links in the source + */ +function linesToParagraph(lines: string[], paragraphs: string[], data: LinkRegistry): void { + if (lines.length !== 0 && lines.join(' ').trim().length !== 0) { paragraphs.push(html`<p class="markdown md-paragraph">${compileInlineConstructs(lines.join(' '), data)}</p>`); } lines.splice(0); -} +} +/** + * Compile all the mark source lines into a string of markdown paragraphs. + * + * @param lines The lines to compile + * @param data The data of all footnotes and named links in the source + * @returns The compiled lines + */ function compileLines(lines: string[], data: LinkRegistry): string[] { const lines_to_convert: string[] = []; const converted_paragraphs: string[] = []; @@ -632,6 +669,12 @@ function compileLines(lines: string[], data: LinkRegistry): string[] { return converted_paragraphs; } +/** + * Search for all footnotes and named links in the given lines of markdown code. + * + * @param lines The lines to search + * @returns The LinkRegistry created from the footnotes + */ function getFootnoteRefs(lines: string[]) { const data: LinkRegistry = {}; let footnote_id = 1; @@ -656,6 +699,27 @@ function getFootnoteRefs(lines: string[]) { return data; } +/** + * This function will compile the given markdown source to a string containing html. + * This compiler supports all basic markdown features and some extended features. The following + * features are supported: + * - Headings + * - Bold, italic and strikethrough + * - Blockquotes + * - Ordered and unordered lists + * - Inline code + * - Horizontal rule + * - Links + * - Images + * - Tables + * - Fenced code blocks + * - Footnotes + * - Heading ids + * - Task list + * + * @param markdown The markdown source + * @returns The compilation output + */ export function compileMarkdown(markdown: string): string { const lines = markdown.split('\n'); const data = getFootnoteRefs(lines); diff --git a/client/src/components/ui/Popup/index.tsx b/client/src/components/ui/Popup/index.tsx index 54258fb08bb2a57729cfb1e142aa378167c57b62..b597f26ed6f47537d5a4a53ca0674f6a1a318616 100644 --- a/client/src/components/ui/Popup/index.tsx +++ b/client/src/components/ui/Popup/index.tsx @@ -10,6 +10,11 @@ interface Props { onClose: Function } +/** + * This is a component that implements a popup. The popup will display the children of the + * component. The onClose callbacks will be called when the popup should be closed. The popup when + * open will prevent scrolling on the body any grey out the background. + */ export default function Popup({ children, onClose }: Props) { useEffect(() => { diff --git a/client/src/components/ui/Project/index.tsx b/client/src/components/ui/Project/index.tsx index 4f4eec2e8013d94a39553d40dcb5e1f9f2f3e36f..1d197fe51c84ef2d752ed5bb9e53df4a337b2c40 100644 --- a/client/src/components/ui/Project/index.tsx +++ b/client/src/components/ui/Project/index.tsx @@ -20,6 +20,10 @@ export interface ProjectProps { demo?: boolean; } +/** + * This is a component that is used in the project grid and shows the information of the given + * project. It will also show the deadline, assignees and completion of the project. + */ export default function Project({ project, large, demo }: ProjectProps) { const [assignees, setAssignees] = useState<AssignedUser[]>([]); const [completion, setCompletion] = useState<Completion>(); diff --git a/client/src/components/ui/ProjectSlide/index.tsx b/client/src/components/ui/ProjectSlide/index.tsx index a5f7a6bbdee89a989e9e73aa05b359d08e264ceb..d622a91170fae6006a6a9a803d2bd08c9312980f 100644 --- a/client/src/components/ui/ProjectSlide/index.tsx +++ b/client/src/components/ui/ProjectSlide/index.tsx @@ -16,6 +16,10 @@ export interface ProjectSlideProps { project: Project; } +/** + * This is a component that is used in the project slider and shows the information of the given + * project. It will also show the deadline, assignees and used time for the project. + */ export default function ProjectSlide({ project }: ProjectSlideProps) { const [assignees, setAssignees] = useState<AssignedUser[]>([]); const [time, setTime] = useState<number>(); diff --git a/client/src/components/ui/Tag/index.tsx b/client/src/components/ui/Tag/index.tsx index 65ad2e37ef0d4a045e1cdd2af6070390c2f596a3..9cadd9090c48e38f8d5b677658055e3b63b82121 100644 --- a/client/src/components/ui/Tag/index.tsx +++ b/client/src/components/ui/Tag/index.tsx @@ -7,6 +7,11 @@ interface Props { color?: string; } +/** + * This is a small component that display the label property using the given color and optionally + * using the given icon. The component styles this information in a certain way. This component is + * used for the status tags of tasks and projects. + */ export default function Tag({ label, icon, color }: Props) { return ( <span className={'tag ' + (color ? 'bg-gradient-horizontal-' + color : '')}> diff --git a/client/src/components/ui/Task/index.tsx b/client/src/components/ui/Task/index.tsx index 0e92f5fed62cff5ce280d3bd6f438fd46ad742aa..afa3021bd412f641ca0d2fbb6e66e5572c465149 100644 --- a/client/src/components/ui/Task/index.tsx +++ b/client/src/components/ui/Task/index.tsx @@ -15,6 +15,10 @@ export interface TaskProps { subtitle?: string; } +/** + * This component shows task information given in the task property. It will also show the given + * subtitle under the name of the task. + */ export default function TaskComponent({ task, subtitle }: TaskProps) { const [assignees, setAssignees] = useState<User[]>([]);