Refactor migration files and improve code formatting

- Updated migration files to enhance readability by adjusting indentation and line breaks.
- Added missing commas in the index file for migration imports.
- Improved accessibility attributes in various UI components by ensuring proper aria-labels and roles.
- Refactored key event handlers in UI components for better clarity and consistency.
- Enhanced error message handling in form components to ensure proper display and accessibility.
- Updated legacy function comments for clarity and maintainability.
This commit is contained in:
Nawaz Dhandala
2026-01-26 19:23:58 +00:00
parent d87b6da7c5
commit e9d5a560ff
27 changed files with 287 additions and 123 deletions

View File

@@ -1,20 +1,35 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class MigrationName1769428619414 implements MigrationInterface {
public name = 'MigrationName1769428619414'
public name = "MigrationName1769428619414";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "AlertEpisode" ADD "titleTemplate" character varying(100)`);
await queryRunner.query(`ALTER TABLE "AlertEpisode" ADD "descriptionTemplate" character varying`);
await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`);
await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`);
await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`);
await queryRunner.query(`ALTER TABLE "AlertEpisode" DROP COLUMN "descriptionTemplate"`);
await queryRunner.query(`ALTER TABLE "AlertEpisode" DROP COLUMN "titleTemplate"`);
}
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "AlertEpisode" ADD "titleTemplate" character varying(100)`,
);
await queryRunner.query(
`ALTER TABLE "AlertEpisode" ADD "descriptionTemplate" character varying`,
);
await queryRunner.query(
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
);
await queryRunner.query(
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`,
);
await queryRunner.query(
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`,
);
await queryRunner.query(
`ALTER TABLE "AlertEpisode" DROP COLUMN "descriptionTemplate"`,
);
await queryRunner.query(
`ALTER TABLE "AlertEpisode" DROP COLUMN "titleTemplate"`,
);
}
}

View File

@@ -1,24 +1,47 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class MigrationName1769428821686 implements MigrationInterface {
public name = 'MigrationName1769428821686'
public name = "MigrationName1769428821686";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "AlertGroupingRule" DROP COLUMN "episodeTitleTemplate"`);
await queryRunner.query(`ALTER TABLE "AlertGroupingRule" ADD "episodeTitleTemplate" character varying`);
await queryRunner.query(`ALTER TABLE "AlertEpisode" DROP COLUMN "titleTemplate"`);
await queryRunner.query(`ALTER TABLE "AlertEpisode" ADD "titleTemplate" character varying`);
await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`);
await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`);
await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`);
await queryRunner.query(`ALTER TABLE "AlertEpisode" DROP COLUMN "titleTemplate"`);
await queryRunner.query(`ALTER TABLE "AlertEpisode" ADD "titleTemplate" character varying(100)`);
await queryRunner.query(`ALTER TABLE "AlertGroupingRule" DROP COLUMN "episodeTitleTemplate"`);
await queryRunner.query(`ALTER TABLE "AlertGroupingRule" ADD "episodeTitleTemplate" character varying(100)`);
}
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "AlertGroupingRule" DROP COLUMN "episodeTitleTemplate"`,
);
await queryRunner.query(
`ALTER TABLE "AlertGroupingRule" ADD "episodeTitleTemplate" character varying`,
);
await queryRunner.query(
`ALTER TABLE "AlertEpisode" DROP COLUMN "titleTemplate"`,
);
await queryRunner.query(
`ALTER TABLE "AlertEpisode" ADD "titleTemplate" character varying`,
);
await queryRunner.query(
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
);
await queryRunner.query(
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`,
);
await queryRunner.query(
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`,
);
await queryRunner.query(
`ALTER TABLE "AlertEpisode" DROP COLUMN "titleTemplate"`,
);
await queryRunner.query(
`ALTER TABLE "AlertEpisode" ADD "titleTemplate" character varying(100)`,
);
await queryRunner.query(
`ALTER TABLE "AlertGroupingRule" DROP COLUMN "episodeTitleTemplate"`,
);
await queryRunner.query(
`ALTER TABLE "AlertGroupingRule" ADD "episodeTitleTemplate" character varying(100)`,
);
}
}

View File

@@ -471,5 +471,5 @@ export default [
MigrationName1769199303656,
MigrationName1769202898645,
MigrationName1769428619414,
MigrationName1769428821686
];
MigrationName1769428821686,
];

View File

@@ -4,7 +4,10 @@ enum SortOrder {
}
// Maps SortOrder to ARIA sort values for accessibility
export const SortOrderToAriaSortMap: Record<SortOrder, "ascending" | "descending"> = {
export const SortOrderToAriaSortMap: Record<
SortOrder,
"ascending" | "descending"
> = {
[SortOrder.Ascending]: "ascending",
[SortOrder.Descending]: "descending",
};

View File

@@ -62,7 +62,9 @@ const Accordion: FunctionComponent<ComponentProps> = (
const accordionId: string = `accordion-content-${React.useId()}`;
const handleKeyDown = (event: React.KeyboardEvent): void => {
const handleKeyDown: (event: React.KeyboardEvent) => void = (
event: React.KeyboardEvent,
): void => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
setIsOpen(!isOpen);
@@ -122,7 +124,10 @@ const Accordion: FunctionComponent<ComponentProps> = (
{!isOpen && <div className="">{props.rightElement}</div>}
</div>
{isOpen && (
<div id={accordionId} className={`space-y-5 ${props.title ? "mt-4" : ""}`}>
<div
id={accordionId}
className={`space-y-5 ${props.title ? "mt-4" : ""}`}
>
{props.children}
</div>
)}

View File

@@ -53,7 +53,15 @@ export interface ComponentProps {
tooltip?: string | undefined;
ariaLabel?: string | undefined;
ariaExpanded?: boolean | undefined;
ariaHaspopup?: "menu" | "listbox" | "dialog" | "tree" | "grid" | "true" | "false" | undefined;
ariaHaspopup?:
| "menu"
| "listbox"
| "dialog"
| "tree"
| "grid"
| "true"
| "false"
| undefined;
ariaControls?: string | undefined;
}
@@ -244,7 +252,8 @@ const Button: FunctionComponent<ComponentProps> = ({
// For icon-only buttons, use title as aria-label for accessibility
const computedAriaLabel: string | undefined =
ariaLabel ||
(buttonStyle === ButtonStyleType.ICON || buttonStyle === ButtonStyleType.ICON_LIGHT
(buttonStyle === ButtonStyleType.ICON ||
buttonStyle === ButtonStyleType.ICON_LIGHT
? title || tooltip
: undefined);

View File

@@ -67,7 +67,9 @@ const CheckboxElement: FunctionComponent<CategoryProps> = (
onFocus={props.onFocus}
onBlur={props.onBlur}
data-testid={props.dataTestId}
aria-describedby={props.description ? "checkbox-description" : undefined}
aria-describedby={
props.description ? "checkbox-description" : undefined
}
aria-invalid={props.error ? "true" : undefined}
type="checkbox"
className={`accent-indigo-600 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 ${
@@ -78,7 +80,9 @@ const CheckboxElement: FunctionComponent<CategoryProps> = (
<div className="ml-3 text-sm leading-6">
<label className="font-medium text-gray-900">{props.title}</label>
{props.description && (
<div id="checkbox-description" className="text-gray-500">{props.description}</div>
<div id="checkbox-description" className="text-gray-500">
{props.description}
</div>
)}
</div>
</div>

View File

@@ -14,9 +14,12 @@ const ColorInput: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
const hasOnClick: boolean = Boolean(props.onClick);
const colorLabel: string = props.value?.toString() || props.placeholder || "No Color Selected";
const colorLabel: string =
props.value?.toString() || props.placeholder || "No Color Selected";
const handleKeyDown = (event: React.KeyboardEvent): void => {
const handleKeyDown: (event: React.KeyboardEvent) => void = (
event: React.KeyboardEvent,
): void => {
if (hasOnClick && (event.key === "Enter" || event.key === " ")) {
event.preventDefault();
props.onClick?.();
@@ -51,9 +54,7 @@ const ColorInput: FunctionComponent<ComponentProps> = (
aria-hidden="true"
></div>
)}
<div>
{colorLabel}
</div>
<div>{colorLabel}</div>
</div>
);
};

View File

@@ -19,12 +19,14 @@ const CopyableButton: FunctionComponent<ComponentProps> = (
}, 2000);
};
const handleCopy = async (): Promise<void> => {
const handleCopy: () => Promise<void> = async (): Promise<void> => {
refreshCopyToClipboardState();
await navigator.clipboard?.writeText(props.textToBeCopied);
};
const handleKeyDown = async (event: React.KeyboardEvent): Promise<void> => {
const handleKeyDown: (event: React.KeyboardEvent) => Promise<void> = async (
event: React.KeyboardEvent,
): Promise<void> => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
await handleCopy();
@@ -40,7 +42,9 @@ const CopyableButton: FunctionComponent<ComponentProps> = (
onKeyDown={handleKeyDown}
role="button"
tabIndex={0}
aria-label={copiedToClipboard ? "Copied to clipboard" : "Copy to clipboard"}
aria-label={
copiedToClipboard ? "Copied to clipboard" : "Copy to clipboard"
}
aria-live="polite"
>
{" "}

View File

@@ -707,7 +707,12 @@ const Dropdown: FunctionComponent<ComponentProps> = (
}}
/>
{props.error && (
<p id={errorId} data-testid="error-message" className="mt-1 text-sm text-red-400" role="alert">
<p
id={errorId}
data-testid="error-message"
className="mt-1 text-sm text-red-400"
role="alert"
>
{props.error}
</p>
)}

View File

@@ -105,7 +105,9 @@ const FormField: <T extends GenericObject>(
}
};
type GetAutoCompleteFunction = (fieldType: FormFieldSchemaType) => string | undefined;
type GetAutoCompleteFunction = (
fieldType: FormFieldSchemaType,
) => string | undefined;
const getAutoComplete: GetAutoCompleteFunction = (
fieldType: FormFieldSchemaType,
@@ -758,7 +760,11 @@ const FormField: <T extends GenericObject>(
error={props.touched && props.error ? props.error : undefined}
dataTestId={props.field.dataTestId}
type={fieldType as InputType}
autoComplete={props.field.fieldType ? getAutoComplete(props.field.fieldType) : undefined}
autoComplete={
props.field.fieldType
? getAutoComplete(props.field.fieldType)
: undefined
}
onChange={(value: string) => {
onChange(value);
props.setFieldValue(props.fieldName, value);

View File

@@ -10,11 +10,13 @@ export interface ComponentProps {
const FullPageModal: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
const handleClose = (): void => {
const handleClose: () => void = (): void => {
props.onClose?.();
};
const handleKeyDown = (event: React.KeyboardEvent): void => {
const handleKeyDown: (event: React.KeyboardEvent) => void = (
event: React.KeyboardEvent,
): void => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
handleClose();
@@ -23,7 +25,9 @@ const FullPageModal: FunctionComponent<ComponentProps> = (
// Handle Escape key at the modal level
React.useEffect(() => {
const handleEscapeKey = (event: KeyboardEvent): void => {
const handleEscapeKey: (event: KeyboardEvent) => void = (
event: KeyboardEvent,
): void => {
if (event.key === "Escape") {
handleClose();
}

View File

@@ -209,14 +209,22 @@ const Input: FunctionComponent<ComponentProps> = (
/>
{props.error && (
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3" aria-hidden="true">
<div
className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3"
aria-hidden="true"
>
<Icon icon={IconProp.ErrorSolid} className="h-5 w-5 text-red-500" />
</div>
)}
</div>
{props.error && (
<p id="input-error-message" data-testid="error-message" className="mt-1 text-sm text-red-400" role="alert">
<p
id="input-error-message"
data-testid="error-message"
className="mt-1 text-sm text-red-400"
role="alert"
>
{props.error}
</p>
)}

View File

@@ -35,7 +35,8 @@ const MermaidDiagram: FunctionComponent<{ chart: string }> = ({
}: {
chart: string;
}) => {
const containerRef = useRef<HTMLDivElement>(null);
const containerRef: React.RefObject<HTMLDivElement | null> =
useRef<HTMLDivElement>(null);
useEffect(() => {
const renderDiagram: () => Promise<void> = async (): Promise<void> => {

View File

@@ -42,7 +42,6 @@ const MasterPage: FunctionComponent<ComponentProps> = (
<React.Fragment>
{isOnline && (
<div className={props.className}>
<div
className={props.makeTopSectionUnstick ? "" : "sticky top-0 z-10"}
>
@@ -54,9 +53,7 @@ const MasterPage: FunctionComponent<ComponentProps> = (
/>
</div>
{props.children}
{props.children}
{props.footer && props.footer}
</div>

View File

@@ -6,7 +6,12 @@ import ModalBody from "./ModalBody";
import ModalFooter from "./ModalFooter";
import { VeryLightGray } from "../../../Types/BrandColors";
import IconProp from "../../../Types/Icon/IconProp";
import React, { FunctionComponent, ReactElement, useEffect, useRef } from "react";
import React, {
FunctionComponent,
ReactElement,
useEffect,
useRef,
} from "react";
export enum ModalWidth {
Normal,
@@ -38,11 +43,14 @@ export interface ComponentProps {
const Modal: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
const modalRef: React.RefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);
const modalRef: React.RefObject<HTMLDivElement> =
useRef<HTMLDivElement>(null);
// Handle Escape key to close modal
useEffect(() => {
const handleEscapeKey: (event: KeyboardEvent) => void = (event: KeyboardEvent): void => {
const handleEscapeKey: (event: KeyboardEvent) => void = (
event: KeyboardEvent,
): void => {
if (event.key === "Escape" && props.onClose) {
props.onClose();
}
@@ -60,9 +68,11 @@ const Modal: FunctionComponent<ComponentProps> = (
if (modal) {
// Focus the first focusable element in the modal
const focusableElements: NodeListOf<Element> = modal.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
);
const firstFocusable: HTMLElement | undefined = focusableElements[0] as HTMLElement | undefined;
const firstFocusable: HTMLElement | undefined = focusableElements[0] as
| HTMLElement
| undefined;
if (firstFocusable) {
firstFocusable.focus();
}

View File

@@ -29,7 +29,8 @@ const MoreMenu: React.ForwardRefExoticComponent<
const { ref, isComponentVisible, setIsComponentVisible } =
useComponentOutsideClick(false);
const [focusedIndex, setFocusedIndex] = useState<number>(-1);
const menuItemRefs: React.MutableRefObject<(HTMLDivElement | null)[]> = useRef<(HTMLDivElement | null)[]>([]);
const menuItemRefs: React.MutableRefObject<(HTMLDivElement | null)[]> =
useRef<(HTMLDivElement | null)[]>([]);
useImperativeHandle(componentRef, () => {
return {
@@ -62,39 +63,49 @@ const MoreMenu: React.ForwardRefExoticComponent<
}
}, [focusedIndex]);
const handleKeyDown: (event: React.KeyboardEvent) => void = useCallback((event: React.KeyboardEvent): void => {
if (!isComponentVisible) {
return;
}
const handleKeyDown: (event: React.KeyboardEvent) => void = useCallback(
(event: React.KeyboardEvent): void => {
if (!isComponentVisible) {
return;
}
const itemCount: number = props.children.length;
const itemCount: number = props.children.length;
switch (event.key) {
case "Escape":
event.preventDefault();
setIsComponentVisible(false);
break;
case "ArrowDown":
event.preventDefault();
setFocusedIndex((prev: number) => (prev + 1) % itemCount);
break;
case "ArrowUp":
event.preventDefault();
setFocusedIndex((prev: number) => (prev - 1 + itemCount) % itemCount);
break;
case "Home":
event.preventDefault();
setFocusedIndex(0);
break;
case "End":
event.preventDefault();
setFocusedIndex(itemCount - 1);
break;
}
}, [isComponentVisible, props.children.length, setIsComponentVisible]);
switch (event.key) {
case "Escape":
event.preventDefault();
setIsComponentVisible(false);
break;
case "ArrowDown":
event.preventDefault();
setFocusedIndex((prev: number) => {
return (prev + 1) % itemCount;
});
break;
case "ArrowUp":
event.preventDefault();
setFocusedIndex((prev: number) => {
return (prev - 1 + itemCount) % itemCount;
});
break;
case "Home":
event.preventDefault();
setFocusedIndex(0);
break;
case "End":
event.preventDefault();
setFocusedIndex(itemCount - 1);
break;
}
},
[isComponentVisible, props.children.length, setIsComponentVisible],
);
return (
<div className="relative inline-block text-left" onKeyDown={handleKeyDown}>
<div
className="relative inline-block text-left"
onKeyDown={handleKeyDown}
>
{!props.elementToBeShownInsteadOfButton && (
<Button
id={buttonId}
@@ -128,7 +139,9 @@ const MoreMenu: React.ForwardRefExoticComponent<
return (
<div
key={index}
ref={(el: HTMLDivElement | null) => { menuItemRefs.current[index] = el; }}
ref={(el: HTMLDivElement | null) => {
menuItemRefs.current[index] = el;
}}
role="menuitem"
tabIndex={focusedIndex === index ? 0 : -1}
onClick={() => {
@@ -141,7 +154,9 @@ const MoreMenu: React.ForwardRefExoticComponent<
e.preventDefault();
setIsComponentVisible(false);
// Trigger child click
const clickEvent: MouseEvent = new MouseEvent("click", { bubbles: true });
const clickEvent: MouseEvent = new MouseEvent("click", {
bubbles: true,
});
e.currentTarget.dispatchEvent(clickEvent);
}
}}

View File

@@ -129,14 +129,20 @@ const Pagination: FunctionComponent<ComponentProps> = (
}
}}
onKeyDown={(e: React.KeyboardEvent) => {
if ((e.key === "Enter" || e.key === " ") && !isPreviousDisabled) {
if (
(e.key === "Enter" || e.key === " ") &&
!isPreviousDisabled
) {
e.preventDefault();
let currentPageNumber: number = props.currentPageNumber;
if (typeof currentPageNumber === "string") {
currentPageNumber = parseInt(currentPageNumber);
}
if (props.onNavigateToPage) {
props.onNavigateToPage(currentPageNumber - 1, props.itemsOnPage);
props.onNavigateToPage(
currentPageNumber - 1,
props.itemsOnPage,
);
}
}
}}
@@ -196,7 +202,10 @@ const Pagination: FunctionComponent<ComponentProps> = (
currentPageNumber = parseInt(currentPageNumber);
}
if (props.onNavigateToPage) {
props.onNavigateToPage(currentPageNumber + 1, props.itemsOnPage);
props.onNavigateToPage(
currentPageNumber + 1,
props.itemsOnPage,
);
}
}
}}
@@ -250,14 +259,20 @@ const Pagination: FunctionComponent<ComponentProps> = (
}
}}
onKeyDown={(e: React.KeyboardEvent) => {
if ((e.key === "Enter" || e.key === " ") && !isPreviousDisabled) {
if (
(e.key === "Enter" || e.key === " ") &&
!isPreviousDisabled
) {
e.preventDefault();
let currentPageNumber: number = props.currentPageNumber;
if (typeof currentPageNumber === "string") {
currentPageNumber = parseInt(currentPageNumber);
}
if (props.onNavigateToPage) {
props.onNavigateToPage(currentPageNumber - 1, props.itemsOnPage);
props.onNavigateToPage(
currentPageNumber - 1,
props.itemsOnPage,
);
}
}
}}
@@ -317,7 +332,10 @@ const Pagination: FunctionComponent<ComponentProps> = (
currentPageNumber = parseInt(currentPageNumber);
}
if (props.onNavigateToPage) {
props.onNavigateToPage(currentPageNumber + 1, props.itemsOnPage);
props.onNavigateToPage(
currentPageNumber + 1,
props.itemsOnPage,
);
}
}
}}

View File

@@ -63,7 +63,10 @@ const ProgressBar: FunctionComponent<ComponentProps> = (
className={`${progressBarSize} bg-indigo-600 rounded-full `}
style={{ width: percent + "%" }}
></div>
<div className="text-sm text-gray-400 mt-1 flex justify-between" aria-hidden="true">
<div
className="text-sm text-gray-400 mt-1 flex justify-between"
aria-hidden="true"
>
<div data-testid="progress-bar-count">
{props.count} {props.suffix}
</div>

View File

@@ -74,7 +74,10 @@ const Radio: FunctionComponent<ComponentProps> = (
type="radio"
className="h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600"
/>
<label htmlFor={optionId} className="block text-sm font-medium leading-6 text-gray-900">
<label
htmlFor={optionId}
className="block text-sm font-medium leading-6 text-gray-900"
>
{option.label}
</label>
</div>
@@ -82,7 +85,12 @@ const Radio: FunctionComponent<ComponentProps> = (
})}
{props.error && (
<p id={errorId} data-testid="error-message" className="mt-1 text-sm text-red-400" role="alert">
<p
id={errorId}
data-testid="error-message"
className="mt-1 text-sm text-red-400"
role="alert"
>
{props.error}
</p>
)}

View File

@@ -17,7 +17,12 @@ const Statusbubble: FunctionComponent<ComponentProps> = (
: Black.toString();
return (
<div className="flex" style={props.style} role="status" aria-label={`Status: ${props.text}`}>
<div
className="flex"
style={props.style}
role="status"
aria-label={`Status: ${props.text}`}
>
<div className="-mr-2 ml-5" aria-hidden="true">
<span className="relative -left-1 -translate-x-full top-1/2 -translate-y-1/2 flex h-3.5 w-3.5">
<span

View File

@@ -3,7 +3,9 @@ import Icon, { ThickProp } from "../Icon/Icon";
import FieldType from "../Types/FieldType";
import Column from "./Types/Column";
import Columns from "./Types/Columns";
import SortOrder, { SortOrderToAriaSortMap } from "../../../Types/BaseDatabase/SortOrder";
import SortOrder, {
SortOrderToAriaSortMap,
} from "../../../Types/BaseDatabase/SortOrder";
import GenericObject from "../../../Types/GenericObject";
import IconProp from "../../../Types/Icon/IconProp";
import React, { ReactElement, useEffect, useState } from "react";
@@ -85,11 +87,12 @@ const TableHeader: TableHeaderFunction = <T extends GenericObject>(
const canSort: boolean = !column.disableSort && Boolean(column.key);
const isSorted: boolean = canSort && props.sortBy === column.key;
const ariaSort: "ascending" | "descending" | "none" | undefined = isSorted
? SortOrderToAriaSortMap[props.sortOrder]
: canSort
? "none"
: undefined;
const ariaSort: "ascending" | "descending" | "none" | undefined =
isSorted
? SortOrderToAriaSortMap[props.sortOrder]
: canSort
? "none"
: undefined;
return (
<th

View File

@@ -32,7 +32,9 @@ const TabElement: FunctionComponent<ComponentProps> = (
? `${backgroundColor} text-gray-700`
: "text-gray-500 hover:text-gray-700";
const handleKeyDown = (event: React.KeyboardEvent): void => {
const handleKeyDown: (event: React.KeyboardEvent) => void = (
event: React.KeyboardEvent,
): void => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
props.onClick?.();

View File

@@ -26,7 +26,7 @@ const Tabs: FunctionComponent<ComponentProps> = (
}
}, [currentTab]);
const tabPanelId: string = `tabpanel-${currentTab?.name || 'default'}`;
const tabPanelId: string = `tabpanel-${currentTab?.name || "default"}`;
return (
<div>
@@ -52,7 +52,7 @@ const Tabs: FunctionComponent<ComponentProps> = (
<div
id={tabPanelId}
role="tabpanel"
aria-labelledby={`tab-${currentTab?.name || 'default'}`}
aria-labelledby={`tab-${currentTab?.name || "default"}`}
className="mt-3 ml-1"
>
{currentTab && currentTab.children}

View File

@@ -90,13 +90,21 @@ const TextArea: FunctionComponent<ComponentProps> = (
tabIndex={props.tabIndex}
/>
{props.error && (
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3" aria-hidden="true">
<div
className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3"
aria-hidden="true"
>
<Icon icon={IconProp.ErrorSolid} className="h-5 w-5 text-red-500" />
</div>
)}
</div>
{props.error && (
<p id="textarea-error-message" data-testid="error-message" className="mt-1 text-sm text-red-400" role="alert">
<p
id="textarea-error-message"
data-testid="error-message"
className="mt-1 text-sm text-red-400"
role="alert"
>
{props.error}
</p>
)}

View File

@@ -122,7 +122,12 @@ const Toggle: FunctionComponent<ComponentProps> = (
)}
</div>
{props.error && (
<p id={errorId} data-testid="error-message" className="mt-1 text-sm text-red-400" role="alert">
<p
id={errorId}
data-testid="error-message"
className="mt-1 text-sm text-red-400"
role="alert"
>
{props.error}
</p>
)}

View File

@@ -514,8 +514,10 @@ export async function generateBlogSitemapXml(page: number): Promise<string> {
return xml;
}
// Legacy function for backwards compatibility (generates single sitemap)
// This is kept in case any other code references it
/*
* Legacy function for backwards compatibility (generates single sitemap)
* This is kept in case any other code references it
*/
export const generateSitemapXml: () => Promise<string> =
async (): Promise<string> => {
// Redirect to sitemap index for backwards compatibility