Skip to content
Closed

- #2964

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
29c087b
fix: lint/typescript errors
JackUait Nov 6, 2025
c434c33
feat: update deps
JackUait Nov 6, 2025
e32ea4c
fix: lint issues in domIterator.ts
JackUait Nov 6, 2025
23f3e90
fix: lint issues in blocks.ts
JackUait Nov 6, 2025
7ad1eed
fix: lint issues in core.ts
JackUait Nov 6, 2025
4e7e384
fix: lint issues in dom.ts
JackUait Nov 6, 2025
4edf334
fix: lint issues in tests
JackUait Nov 6, 2025
80be68b
test: skip copy-paste test
JackUait Nov 6, 2025
4dd1cdb
fix: lint issues in flipper.ts
JackUait Nov 7, 2025
81dc13e
fix: lint issues in polyfills.ts
JackUait Nov 7, 2025
75dde42
fix: lint issues in selection.ts
JackUait Nov 7, 2025
4762b10
fix: lint issues in utils.ts
JackUait Nov 7, 2025
5d25817
fix: lint issues in api.ts
JackUait Nov 7, 2025
ca50d78
fix: lint issues in index.ts
JackUait Nov 7, 2025
c489d02
fix: lint issues in namespace-internal.ts
JackUait Nov 7, 2025
1a6049c
fix: lint issues in inline-tool-bold.ts
JackUait Nov 7, 2025
bc540d1
fix: lint issues in tests
JackUait Nov 7, 2025
614cbc4
fix: lint issues in codex.ts
JackUait Nov 7, 2025
e3a67dc
fix: lint issues in __module.ts
JackUait Nov 7, 2025
7940e12
test: write tests for inline bold tool
JackUait Nov 8, 2025
6a6c873
chore: restore execCommand in selection.ts
JackUait Nov 8, 2025
0a23e92
fix: replace execCommand in selection.ts
JackUait Nov 8, 2025
02c8bd4
fix: lint issues in inline-tool-link.ts
JackUait Nov 8, 2025
7107717
test: add data selectors for states of inline-tool-link
JackUait Nov 8, 2025
fdcfef6
test: add tests for inline-link-tool
JackUait Nov 10, 2025
0779917
fix: lint issues in inline-tool-bold.ts
JackUait Nov 10, 2025
1a8ec55
feat: make all test cases of inline-tool-bold work
JackUait Nov 10, 2025
ec28650
fix: make ALL tests in inline-tool-bold pass
JackUait Nov 10, 2025
f26202e
fix: get rid of deprecated API in inline-tool-bold.ts
JackUait Nov 10, 2025
117bc0e
test: add tests for popover search
JackUait Nov 10, 2025
ff118c4
fix: remove left deprecated APIs from inline-tool-bold.ts
JackUait Nov 10, 2025
fb23298
test: make sure that E2E tests always run with the latest changes
JackUait Nov 10, 2025
24b13ad
test: add move the tests that were left in Cypress for popover-search…
JackUait Nov 10, 2025
7d284c0
test: move sanitisation tests from Cypress to Playwright
JackUait Nov 10, 2025
d14b971
test: add tests for popover search
JackUait Nov 10, 2025
bd40b0f
test: add tests for sanitisation
JackUait Nov 10, 2025
3ec36a5
test: add tests for i18n
JackUait Nov 10, 2025
f02e838
fix: write tests for tooltip.ts and fix lint issues
JackUait Nov 11, 2025
1548a56
fix: add unit tests and fix lint issues for sanitizer.ts
JackUait Nov 11, 2025
8372ee4
fix: add tests and fix lint issues in popover-desktop.ts
JackUait Nov 11, 2025
f362da6
fix: styles for tooltip.ts
JackUait Nov 11, 2025
1bd18fe
test: add additional E2E tests for tooltip
JackUait Nov 11, 2025
cce5037
fix: add tests and fix lint issues in toolbox.ts
JackUait Nov 11, 2025
cae0b37
fix: add tests and fix lint issues in caret.ts
JackUait Nov 11, 2025
6741862
deps: remove redunant dependency codex-tooltip
JackUait Nov 11, 2025
334b859
fix: add tests and fix lint issues for blocks.ts/block.ts
JackUait Nov 11, 2025
41484ab
fix: add tests and fix lint issues for some files
JackUait Nov 12, 2025
3b97e0f
fix: lint issues fixed and tests added for modules
JackUait Nov 13, 2025
d4c7356
fix: lint issues and add tests for the left modules
JackUait Nov 13, 2025
0379064
test: move part of the tests from Cypress to Playwright
JackUait Nov 14, 2025
b827e4a
test: move ALL tests from Cypress to Playwright
JackUait Nov 14, 2025
b677b63
fix: all typescript errors
JackUait Nov 15, 2025
1d6d0a4
fix: left typescript errors
JackUait Nov 15, 2025
c6fc903
fix: all eslint issues
JackUait Nov 15, 2025
6a64b13
fix: get rid of all nested if statements
JackUait Nov 15, 2025
d5ba62f
test: cover untested parts with tests
JackUait Nov 15, 2025
799cf60
chore: introduce new tests and fix typescript/eslint errors
JackUait Nov 15, 2025
b89af36
fix: replace deprecated APIs with the modern ones
JackUait Nov 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
"version": "0.2",
"language": "en",
"words": [
"autofocused",
"behaviour",
"behaviours",
"Behaviour",
"cacheable",
"Cantarell",
"chainer",
"Chainer",
"chatbots",
"childs",
"codexteam",
"colspan",
"constructables",
"contenteditable",
"Contenteditable",
"contentless",
"Contentless",
"convertable",
"Convertable",
"convertible",
"Convertible",
"cssnano",
"cssnext",
"Debouncer",
"devserver",
"editorjs",
"Editorjs",
"entrypoints",
"Flippable",
"flippable",
"GRAMMARLY",
"Gfycat",
"hsablonniere",
"hspace",
"intellij",
"keydown",
"keydowns",
"Kilian",
"leftarrow",
"licence",
"mergeable",
"movetostart",
"mouseleave",
"navigatable",
"nofollow",
"opencollective",
"preconfigured",
"radiobutton",
"resetors",
"rowspan",
"Segoe",
"selectall",
"sometool",
"strongs",
"stylelint",
"textareas",
"toolname",
"twitterwidget",
"typeof",
"UPLUCID",
"Unmergeable",
"rgba",
"Roboto",
"Fira",
"Neue",
"grayscale",
"Menlo",
"Consolas",
"viewports",
"sonarjs",
"Unregisters",
"IAPI",
"Jamison",
"Minzipped",
"srcset",
"youtu",
"Dont",
"CONTENTLESS",
"autofocusable",
"Pettit"
],
"ignorePaths": [
"dist/**",
"node_modules/**",
"test-results/**",
"cypress/downloads/**"
],
"flagWords": [],
"ignoreRegExpList": [
"/[\\u0080-\\uFFFF]+/",
"/\"[A-Za-z0-9]{8,}\"/"
]
}

23 changes: 23 additions & 0 deletions .cursor/rules/do-not-modify-configs.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
alwaysApply: true
---

# Rule: DO NOT MODIFY configuration files unless explicitly instructed

## Description
You MUST **never modify any configuration files** (such as `vite.config.ts`, `tsconfig.json`, `.eslintrc`, `package.json`, `.env`, etc.) **unless explicitly told to do so** in the current request or accompanying instructions.

## Examples

✅ **Allowed**
- Editing TypeScript source files, tests, or component code.
- Updating imports, logic, or styles within non-config files.
- Adding configuration changes **only when explicitly requested** (e.g., “Add a new alias in `vite.config.ts`”).

❌ **Not Allowed**
- Modifying or creating any config files without explicit instruction.
- Automatically adding dependencies or changing build/test settings.
- Altering environment variables or global project settings without being told to.

## Enforcement
If you believe a configuration change might be required, **ask for confirmation first** before proceeding.
23 changes: 23 additions & 0 deletions .cursor/rules/fix-problems.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
alwaysApply: true
---

# Fix Problems Policy

## Core Principle
VERY IMPORTANT: When encountering ANY problem in the code—such as TypeScript errors, linting issues, runtime bugs, accessibility violations, or performance problems—you or any other problem MUST find a proper way to fix it. Do NOT silence, suppress, or avoid the problem using workarounds like `// @ts-ignore`, `any` types, or ignoring linter warnings.

## Preferred Approaches
- **Refactor for correctness**: Resolve issues by improving the code structure, using precise types, type guards, proper error handling, and best practices.
- **Investigate root causes**: Use tools like debugging, logging, or code searches to understand why the problem occurs before fixing it.
- **Align with existing rules**: Follow related policies such as the Fix TypeScript Errors Policy (adapt for other languages), ESLint configurations, and accessibility guidelines.
- **Test the fix**: After fixing, verify with tests, linting runs (e.g., `yarn lint:fix`), or manual checks to ensure the problem is truly resolved without introducing new issues.

## When to Apply
- During any code editing, reviewing, or generation task.
- Proactively scan for and fix problems in affected files using available tools (e.g., read_lints, grep, codebase_search).
- If a problem persists after reasonable efforts, document it clearly and suggest next steps rather than suppressing it.

## Notes
- This policy promotes robust, high-quality code that is easier to maintain and less prone to future issues.
- If unsure how to fix a problem, use tools to gather more information or break it into smaller, solvable parts rather than bypassing it.
119 changes: 119 additions & 0 deletions .cursor/rules/src/frontend/accessibility.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
---
alwaysApply: true
description: Enforce accessibility best practices so all users can use the application
---

### Accessibility guidance (must follow)

- Semantics first
- Prefer semantic HTML (`button`, `a`, `nav`, `main`, `header`, `footer`, `ul/ol/li`, `table/th/td`) over generic `div`/`span`.
- Use `button` for actions and `a`/`Link` for navigation. Do not use click handlers on non-interactive elements. If unavoidable, add `role="button"`, `tabIndex={0}`, and keyboard handlers for Enter/Space.

- Keyboard support
- All interactive controls must be reachable via Tab and operable via keyboard.
- Do not remove focus outlines. If customizing, ensure visible `:focus-visible` styles with sufficient contrast.
- Preserve a logical tab order; avoid `tabIndex` > 0.

- Focus management
- On opening modals/drawers/popovers: move focus inside, trap focus, and restore focus to the trigger on close.
- Provide a skip link to main content (e.g., `href="#main"`) and landmark roles (`<main>`, `<nav>`, `<header>`, `<footer>`).

- Images and media
- Every `img` must have an appropriate `alt`. If decorative, use `alt=""` and `aria-hidden="true"`.
- Provide captions/subtitles for video/audio when applicable.
- For lazy-loaded images with skeletons, mark skeletons `aria-hidden="true"` and set container `aria-busy` while loading.

- Forms
- Inputs require visible labels bound via `<label htmlFor>` or `aria-label`/`aria-labelledby`.
- Indicate errors with `aria-invalid` and associate helper/error text via `aria-describedby`.

- Live updates and async content
- For dynamic status (loading/completion), use `aria-live="polite"` (or `assertive` if critical).
- Spinners should have `aria-label` or be hidden (`aria-hidden="true"`) with a separate live region announcing status.

- Headings and structure
- Maintain a logical heading hierarchy without skipping levels.
- Use list semantics for collections.

- Color and contrast
- Ensure WCAG 2.1 AA contrast: 4.5:1 for normal text and 3:1 for large or bold text and UI components, including focus and hover states. When placing text over images, add an overlay or background.
- Do not convey information by color alone; add icons/text.

- Motion and reduced motion
- Respect `prefers-reduced-motion: reduce`. Disable or simplify non-essential animations.
- In React animations, gate effects with `gsap.matchMedia('(prefers-reduced-motion: no-preference)')` and provide a reduced-motion path.
- Example usage exists in [AnnouncementsFeedContent.tsx](mdc:src/frontend/src/features/AnnouncementsFeed/ui/AnnouncementsFeedContent.tsx).
- Vanilla CSS example using the `prefers-reduced-motion` media query:

```css
/* Default animations */
.card {
transition: transform 300ms ease, opacity 300ms ease;
}
.card:hover {
transform: translateY(-4px);
opacity: 0.95;
}

/* Reduced motion: remove transforms and long transitions */
@media (prefers-reduced-motion: reduce) {
* {
animation: none !important;
transition-duration: 0.01ms !important; /* effectively no transition */
scroll-behavior: auto !important;
}
.card:hover {
transform: none;
opacity: 1;
}
}
```

- Tables and data
- Use `<th scope>` for headers, provide captions when helpful. Avoid layout tables.

- Testing
- Prefer `@testing-library` queries by role/name (`getByRole`, `getByLabelText`) to reflect real accessibility.

### React implementation tips

- Announce route changes by updating `document.title` and placing page content in a `<main id="main">` region.
- When building composite widgets (tabs, accordions), follow the relevant ARIA patterns (roles, `aria-selected`, `aria-controls`) only when semantics are not achievable with native elements.
- For card components that wrap links, ensure the entire card is a single focusable link (as with `Link`) and include descriptive link text or `aria-label` if needed.

### Code patterns

```tsx
// Accessible button vs. link
<button type="button" onClick={handleAction}>Do action</button>
<Link to="/path">Go to details</Link>

// Custom interactive element (only if you cannot use <button>)
<div
role="button"
tabIndex={0}
onKeyDown={(e) => {
const isEnter = e.key === 'Enter' || e.code === 'Enter';
const isSpace = e.key === ' ' || e.key === 'Spacebar' || e.code === 'Space';

if (isEnter) {
onClick();
}
if (isSpace) {
e.preventDefault();
}
}}
onKeyUp={(e) => {
const isSpace = e.key === ' ' || e.key === 'Spacebar' || e.code === 'Space';
if (isSpace) {
onClick();
}
}}
onClick={onClick}
/>
```

### Notes

- Use ARIA to enhance semantics, not replace them. Avoid redundant roles on native elements.
- If a component is purely decorative (e.g., background clouds), set `aria-hidden="true"` and remove from the tab order.
27 changes: 27 additions & 0 deletions .cursor/rules/src/frontend/code-style-eslint.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: Frontend ESLint Code Style
alwaysApply: true
description: Defer all code style decisions to the project's ESLint configuration; do not invent new style rules
---

### Code Style Source of Truth

- **Always defer to ESLint configuration** for any code style, formatting, or lint rules.
- **Do not create or enforce custom style rules** beyond what ESLint (and its plugins) already defines in this repo.

### Where the rules live

- Frontend config: [eslint.config.js](mdc:src/frontend/eslint.config.js)
- AppShell config: [.eslintrc.js](mdc:src/Dodo.KnowledgeBase.Web/appshell/.eslintrc.js)

### How to apply

- When unsure about style (imports order, quote style, indentation, prop ordering, hooks rules, etc.), consult the ESLint configs above and follow them as-is.
- Prefer using the repo scripts to validate/fix:
- `yarn lint`
- `yarn lint:fix`

### Notes

- If ESLint and Prettier interact, follow the ESLint-integrated Prettier setup from the configs.
- For styles-in-JS (e.g., styled-components), follow any ESLint plugin guidance present; do not invent property ordering rules.
22 changes: 22 additions & 0 deletions .cursor/rules/src/frontend/fix-typescript-errors.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
alwaysApply: true
globs: *.ts,*.tsx
description: Enforce fixing TypeScript errors by improving code quality, not suppressing them
---

# Fix TypeScript Errors Policy

- **Core Principle**: Always resolve TypeScript errors by refactoring code to be type-safe, rather than suppressing them with `any`, `// @ts-ignore`, or similar workarounds.
- **Preferred Approaches**:
- Use precise types, type guards, discriminated unions, and proper narrowing to eliminate errors.
- Avoid the non-null assertion operator (`!`) and `any` types as per project guidelines.
- Refactor functions, components, and logic to align with TypeScript's type system.
- **When to Apply**:
- For any TypeScript files (`.ts`, `.tsx`), prioritize fixing errors during edits.
- After making changes, run `yarn lint:fix` or similar commands to ensure compliance.
- **Alignment with Existing Rules**:
- This reinforces the ESLint Fix-First Policy: Fix issues flagged by TypeScript/ESLint by improving code, not silencing linters.
- Ensure accessibility and best practices are maintained while resolving types.
- **Notes**:
- If a TypeScript error persists after reasonable refactoring, consult the ESLint configuration or seek clarification on intended behavior, but do not suppress it locally.
- Promote code that is both type-safe and adheres to React/JS best practices.
69 changes: 69 additions & 0 deletions .cursor/rules/src/frontend/frontend-simplicity.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
alwaysApply: true
globs: "*.ts","*.tsx","*.js","*.jsx","src/frontend/**"
description: "Frontend development principle: Keep solutions simple and avoid overengineering"
---

# Frontend Simplicity Principle

When working on frontend tasks, prioritize simple, straightforward solutions over complex implementations.

## Guidelines

### Keep it simple
- **Prefer basic approaches**: Choose standard patterns over custom abstractions unless there's a clear benefit
- **Avoid premature optimization**: Don't add complexity for performance gains that haven't been measured
- **Use existing libraries**: Leverage well-established libraries rather than building custom solutions

### Component design
- **Single responsibility**: Components should do one thing well
- **Avoid deep nesting**: Keep component trees shallow and manageable
- **Prefer composition over inheritance**: Use composition patterns for reusable behavior

### State management
- **Local state first**: Use local component state before reaching for global state management
- **Simple patterns**: Prefer useState/useReducer over complex state machines unless necessary
- **Avoid over-abstraction**: Don't create unnecessary abstractions for simple state logic

### Code organization
- **Clear naming**: Use descriptive names that explain the purpose
- **Minimal files**: Avoid splitting simple features across multiple files
- **Straightforward logic**: Write code that's easy to follow and debug

### When complexity is justified
Only add complexity when:
- It solves a measured performance problem
- It significantly improves user experience
- It enables critical functionality
- The team agrees it's necessary

## Examples

```tsx
// ✅ Simple and clear
const UserProfile = ({ user }) => {
const [isEditing, setIsEditing] = useState(false);

return (
<div>
<h2>{user.name}</h2>
{isEditing ? (
<EditForm onSave={() => setIsEditing(false)} />
) : (
<button onClick={() => setIsEditing(true)}>Edit</button>
)}
</div>
);
};

// ❌ Overcomplicated
const UserProfile = ({ user }) => {
const [state, dispatch] = useReducer(profileReducer, initialProfileState);
const editingContext = useContext(EditingContext);
const formManager = useFormManager();

// Complex logic that could be simplified...
};
```

Remember: Code is read more than it's written. Choose the solution that future developers can understand quickly.
Loading