chore(preview): fix pre-existing CI drift (web format + i18n types + oxlint warnings)#23
Merged
Conversation
added 2 commits
May 21, 2026 13:25
…+ oxlint warnings
Two pre-existing problems on preview were blocking any PR touching apps/web
or @plane/i18n from going green:
1. oxfmt --check flagged 5 web files as unformatted drift (none owned by a
single PR). Ran oxfmt --write on:
- apps/web/app/(all)/lark-quick-create/page.tsx
- apps/web/ce/components/automations/root.tsx
- apps/web/core/components/profile/overview/workload.tsx
- apps/web/core/components/workspace/settings/lark-invite-modal.tsx
- apps/web/core/services/project/project-automation.service.ts
Pure whitespace / line-wrapping; no behavior change.
2. @plane/i18n tsc --noEmit failed at src/store/index.ts:68 with
"Property 'env' does not exist on type 'ImportMeta'". The repo has no
vite-env.d.ts ambient declaration anywhere, and this is the only
import.meta.env usage in the package. Inline cast to a minimal typed
shape — single line, no new file, no `any`.
3. The 5 web files also had 16 pre-existing oxlint warnings flagged the
moment lint-staged ran on them. CI tolerates 11957 warnings on web, but
the pre-commit hook uses --deny-warnings (0 tolerance). Fixed in place:
- 8 unused vars → underscore-prefixed (the rule's own suggested fix)
- 2 s.onload= / s.onerror= → addEventListener (mechanical)
- 2 await-in-loop (sequential SDK fallback) → eslint-disable-next-line
with reason ("intentional sequential CDN fallback")
- 2 key={idx} on local-state lists with no stable id →
eslint-disable-next-line with reason
- 1 <a> with no href on a non-link wrapper → replaced with <div>
(closest non-anchor element)
- 1 .then() missing return → added explicit `return;`
Effect: any PR touching apps/web or @plane/i18n will pass check:format,
check:types, and pre-commit lint-staged again. Unblocks PR #21.
… i18n no longer short-circuits tsc
After the i18n fix in the previous commit, tsc no longer fails fast on
@plane/i18n, so check:types finally runs against apps/web — and surfaces
11 type errors that have been sitting on preview unnoticed:
1. Button variant="neutral-primary" (5 occurrences). The propel Button
variant union was narrowed to remove neutral-primary; consumers were
never updated. Closest semantic = "secondary" (bordered neutral button
used for lower-emphasis actions next to a "primary" Add/Submit).
- apps/web/.../members/page.tsx (2x: "Sync from Lark", "Invite from Lark")
- apps/web/.../lark-invite-modal.tsx (1x: Cancel)
- apps/web/.../lark-quick-create/page.tsx (1x: Cancel)
Plus the 2nd "Invite from Lark" instance.
2. Button size="md" (2 occurrences). Same story for size — "md" was removed,
the previous default-equivalent is "base".
- apps/web/.../lark-invite-modal.tsx (Cancel + Invite N members)
3. `catch (err: unknown)` chains that produce `unknown | string` instead of
`string` (2 occurrences). The pattern
const message = (err && typeof err === "object" && "error" in err && (err as {error?: string}).error) || "fallback"
returns `unknown | string` (because `err && X` returns `err` when `err` is
falsy, and `err` is `unknown`). Rewrote with explicit narrowing + a
`string` accumulator. Behavior unchanged.
- apps/web/.../members/page.tsx (line 174-178)
- apps/web/.../lark-invite-modal.tsx (line 120-124)
4. TLarkContact verbatim-import error (1 occurrence). TypeScript 5+ with
verbatimModuleSyntax requires `import type` for type-only symbols.
- apps/web/.../lark-invite-modal.tsx (line 14): split into
`import type { TLarkContact }` and `import { WorkspaceService }`.
5. MemberDropdown multiple={false} prop mismatch (1 issue, 2 lines).
The MemberDropdownProps union narrows by `multiple`:
multiple: false → value: string|null, onChange: (string|null)=>void
multiple: true → value: string[], onChange: (string[])=>void
lark-quick-create was passing `value={[id]}` and `onChange: (ids: string[])`
under `multiple={false}`, which only the `true` branch accepts. Switched
to the correct `multiple: false` shape.
- apps/web/.../lark-quick-create/page.tsx (line 658-659)
6. fetchWorkspaceMembers callback signature mismatch (1 occurrence). The
store returns `IWorkspaceMember[]` but the call site treats each member
as a defensive `Record<string, unknown>` (member-object vs flat — depends
on API shape evolution). Added an explicit boundary cast and let `.map`
infer the parameter type. Behavior unchanged.
- apps/web/.../lark-quick-create/page.tsx (line 391-392)
apps/web `tsc --noEmit` now passes (exit 0), apps/web `oxlint
--deny-warnings` passes on the 3 modified files, and `oxfmt --check` passes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
origin/previewhad three categories of pre-existing CI drift that silently blocked any PR touchingapps/webor@plane/i18nfrom going green — surfaced while trying to land PR #21 (sort by custom field):check:formatfailed on 5 unformatted web files (none owned by a single PR; left-over whitespace drift).check:typesfailed in@plane/i18non aimport.meta.envaccess with noImportMeta.envtype declaration anywhere in the repo.pre-commit(lint-staged) hook failed on the same 5 files: CI tolerates 11957 oxlint warnings on web (--max-warnings), but the pre-commit hook uses--deny-warnings(0 tolerance). The moment any author runsoxfmt --writeon these files, lint-staged exposes 16 pre-existing warnings and refuses to commit.PR #22 (docs only) passed cleanly because turbo
--affectedcorrectly skipped web/i18n. Any other PR is blocked.What
Fix 1 —
oxfmt --writeon 5 web filesPure whitespace / line-wrapping. No behavior change.
Fix 2 —
import.meta.envtype in@plane/i18nThe package has no
vite-env.d.tsand this is the onlyimport.meta.envusage in it. Minimal inline typed cast — single line, no new file, noany:Fix 3 — clear 16 pre-existing oxlint warnings exposed in fix 1
Categorized:
s.onload = …s.addEventListener("load", …)(mechanical)awaitinside sequential CDN-fallback loop// eslint-disable-next-line no-await-in-loop+ reason —Promise.allwould change behavior (parallelize)key={idx}on local-state lists (no stable id, no reorder UI)// eslint-disable-next-line react/no-array-index-key+ reason<a>with nohrefon a non-link wrapper<div>(closest non-anchor element, zero behavior change).then()missing explicit returnreturn;Total: +228 / −314 lines, of which most are whitespace re-wrap. Net real change is small.
Test plan
feat/list-sort-by-custom-field) CI re-runs go green without touching its own diff