@propriety/court-calendar 1.0.157 → 1.0.158
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/extensions.json +108 -0
- package/dist/__tests__/ApiFailureReporter.test.d.ts +1 -0
- package/dist/__tests__/CopyChip.test.d.ts +1 -0
- package/dist/__tests__/helpers/api/apiFailures.test.d.ts +1 -0
- package/dist/_components/ErrorReport/ApiFailureReporter.d.ts +14 -0
- package/dist/_components/Modal/CaseDetails/CopyChip.d.ts +13 -0
- package/dist/helpers/api/apiFailures.d.ts +68 -0
- package/dist/helpers/clipboard.d.ts +9 -0
- package/dist/hooks/UseModalActions.d.ts +3 -2
- package/dist/index.mjs +8153 -7878
- package/package.json +1 -1
- package/src/__tests__/ApiFailureReporter.test.tsx +171 -0
- package/src/__tests__/CopyChip.test.tsx +54 -0
- package/src/__tests__/CreateEditCaseOpenCases.test.tsx +18 -2
- package/src/__tests__/helpers/api/apiFailures.test.ts +305 -0
- package/src/__tests__/hooks/UseModalActions.test.ts +39 -0
- package/src/_components/CCalendar.tsx +5 -0
- package/src/_components/DebugModal/Dashboard.tsx +6 -2
- package/src/_components/ErrorReport/ApiFailureReporter.tsx +151 -0
- package/src/_components/List/CalendarList.tsx +6 -3
- package/src/_components/Modal/CaseDetails/CaseDetails.tsx +11 -27
- package/src/_components/Modal/CaseDetails/CopyChip.tsx +55 -0
- package/src/_components/Modal/DateDetails/CaseViewer.tsx +24 -4
- package/src/_components/Modal/DateEdit/CreateEditCase.tsx +23 -11
- package/src/_components/Modal/Modal.tsx +13 -2
- package/src/helpers/api/apiFailures.ts +234 -0
- package/src/helpers/api/cases.ts +96 -62
- package/src/helpers/api/courtDates.ts +57 -42
- package/src/helpers/clipboard.ts +36 -0
- package/src/hooks/UseModalActions.ts +29 -15
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Stack for this repo: React 19 + TypeScript + Vite (library mode) + Biome + Vitest + MUI 5.
|
|
3
|
+
// NOTE: "unwantedRecommendations" only suppresses VS Code's recommendation prompts.
|
|
4
|
+
// It does NOT disable an installed extension. To actually disable, either:
|
|
5
|
+
// a) Extensions view -> right-click -> "Disable (Workspace)", or
|
|
6
|
+
// b) import the profile at .vscode/court-calendar.code-profile (see README note below).
|
|
7
|
+
"recommendations": [
|
|
8
|
+
"biomejs.biome",
|
|
9
|
+
"yoavbls.pretty-ts-errors",
|
|
10
|
+
"antfu.vite",
|
|
11
|
+
"christian-kohler.path-intellisense",
|
|
12
|
+
"christian-kohler.npm-intellisense",
|
|
13
|
+
"eamodio.gitlens",
|
|
14
|
+
"github.vscode-pull-request-github"
|
|
15
|
+
],
|
|
16
|
+
|
|
17
|
+
"unwantedRecommendations": [
|
|
18
|
+
// --- Formatter/linter conflicts: this repo uses Biome exclusively ---
|
|
19
|
+
"esbenp.prettier-vscode",
|
|
20
|
+
"dbaeumer.vscode-eslint",
|
|
21
|
+
"inferrinizzard.prettier-sql-vscode",
|
|
22
|
+
|
|
23
|
+
// --- Python stack (lives in ../adminAPI, ../Utility-API, ../pdfOcr) ---
|
|
24
|
+
"ms-python.python",
|
|
25
|
+
"ms-python.vscode-pylance",
|
|
26
|
+
"ms-python.debugpy",
|
|
27
|
+
"ms-python.black-formatter",
|
|
28
|
+
"ms-python.isort",
|
|
29
|
+
"ms-python.vscode-python-envs",
|
|
30
|
+
"charliermarsh.ruff",
|
|
31
|
+
"kevinrose.vsc-python-indent",
|
|
32
|
+
|
|
33
|
+
// --- Jupyter ---
|
|
34
|
+
"ms-toolsai.jupyter",
|
|
35
|
+
"ms-toolsai.jupyter-renderers",
|
|
36
|
+
"ms-toolsai.jupyter-keymap",
|
|
37
|
+
"ms-toolsai.vscode-jupyter-cell-tags",
|
|
38
|
+
"ms-toolsai.vscode-jupyter-slideshow",
|
|
39
|
+
|
|
40
|
+
// --- .NET / C# ---
|
|
41
|
+
"ms-dotnettools.csharp",
|
|
42
|
+
"ms-dotnettools.csdevkit",
|
|
43
|
+
"ms-dotnettools.vscode-dotnet-runtime",
|
|
44
|
+
|
|
45
|
+
// --- C / C++ / shaders ---
|
|
46
|
+
"ms-vscode.cpptools",
|
|
47
|
+
"jbenden.c-cpp-flylint",
|
|
48
|
+
"slevesque.shader",
|
|
49
|
+
|
|
50
|
+
// --- AutoHotkey (three overlapping extensions) ---
|
|
51
|
+
"cweijan.vscode-autohotkey-plus",
|
|
52
|
+
"mark-wiemer.vscode-autohotkey-plus-plus",
|
|
53
|
+
"thqby.vscode-autohotkey2-lsp",
|
|
54
|
+
|
|
55
|
+
// --- Other frameworks not used here (MUI + Emotion, no Tailwind/Vue/Sass) ---
|
|
56
|
+
"vue.volar",
|
|
57
|
+
"bradlc.vscode-tailwindcss",
|
|
58
|
+
"austenc.tailwind-docs",
|
|
59
|
+
"syler.sass-indented",
|
|
60
|
+
"glenn2223.live-sass",
|
|
61
|
+
|
|
62
|
+
// --- AWS / containers (belongs to ../lambdas) ---
|
|
63
|
+
"amazonwebservices.aws-toolkit-vscode",
|
|
64
|
+
"ms-azuretools.vscode-containers",
|
|
65
|
+
"ms-vscode-remote.remote-containers",
|
|
66
|
+
|
|
67
|
+
// --- Static/live servers: superseded by `npm run dev` (Vite) ---
|
|
68
|
+
"ritwickdey.liveserver",
|
|
69
|
+
"ms-vscode.live-server",
|
|
70
|
+
"george-alisson.html-preview-vscode",
|
|
71
|
+
"antfu.browse-lite",
|
|
72
|
+
|
|
73
|
+
// --- Redundant with built-in editor features (see .vscode/settings.json) ---
|
|
74
|
+
"formulahendry.auto-rename-tag",
|
|
75
|
+
"formulahendry.auto-close-tag",
|
|
76
|
+
"steoates.autoimport",
|
|
77
|
+
"kevinmcgowan.typescriptimport",
|
|
78
|
+
"donjayamanne.githistory",
|
|
79
|
+
"xyz.local-history",
|
|
80
|
+
|
|
81
|
+
// --- Continuous-CPU novelty extensions ---
|
|
82
|
+
"tonybaloney.vscode-pets",
|
|
83
|
+
"hoovercj.vscode-power-mode",
|
|
84
|
+
|
|
85
|
+
// --- Heavy eager extensions with no role in this repo ---
|
|
86
|
+
"shd101wyy.markdown-preview-enhanced",
|
|
87
|
+
"zignd.html-css-class-completion",
|
|
88
|
+
"ecmel.vscode-html-css",
|
|
89
|
+
"hwencc.html-tag-wrapper",
|
|
90
|
+
"kisstkondoros.vscode-gutter-preview",
|
|
91
|
+
"alefragnani.project-manager",
|
|
92
|
+
"ms-vsliveshare.vsliveshare",
|
|
93
|
+
"tamasfe.even-better-toml",
|
|
94
|
+
|
|
95
|
+
// --- Data/document viewers ---
|
|
96
|
+
"grapecity.gc-excelviewer",
|
|
97
|
+
"muhammad-ahmad.xlsx-viewer",
|
|
98
|
+
"mechatroner.rainbow-csv",
|
|
99
|
+
"tomoki1207.pdf",
|
|
100
|
+
|
|
101
|
+
// --- Misc unused languages ---
|
|
102
|
+
"eww-yuck.yuck",
|
|
103
|
+
"andrejunges.handlebars",
|
|
104
|
+
"mrmlnc.vscode-json5",
|
|
105
|
+
"idered.npm",
|
|
106
|
+
"petekinnecom.terminal-command-keys"
|
|
107
|
+
]
|
|
108
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single place a failed API call becomes visible.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately **persistent** — no `autoHideDuration`. A four-second toast is how a failed
|
|
5
|
+
* delete went unnoticed in the first place; an error the user needs to report has to wait for
|
|
6
|
+
* them. Anchored top-center so it never collides with the transient bottom-center snackbars
|
|
7
|
+
* (saved / hidden-by-filter / bootstrap) that the calendar already uses.
|
|
8
|
+
*
|
|
9
|
+
* Mount once, high in the tree. It subscribes to the module-level failure bus in
|
|
10
|
+
* `helpers/api/apiFailures`, so it needs no props from the call sites that fail.
|
|
11
|
+
*/
|
|
12
|
+
export default function ApiFailureReporter({ activeUser }: {
|
|
13
|
+
activeUser?: number;
|
|
14
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Click-to-copy chip used for the identity fields on the Case Details panel
|
|
3
|
+
* (parcel ID, SCAR index number). Each instance owns its own "Copied!" state so
|
|
4
|
+
* copying one field never flips the tooltip on another.
|
|
5
|
+
*
|
|
6
|
+
* Renders as a `span` by default: `InfoField` wraps its value in a `Typography`
|
|
7
|
+
* (a `<p>`), and a `div` inside a `<p>` is invalid nesting.
|
|
8
|
+
*/
|
|
9
|
+
export default function CopyChip({ value, size, component, }: {
|
|
10
|
+
value: string;
|
|
11
|
+
size?: 'small' | 'medium';
|
|
12
|
+
component?: React.ElementType;
|
|
13
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A cross-cutting sink for API failures, so a request the server rejected always reaches the
|
|
3
|
+
* screen instead of only the console.
|
|
4
|
+
*
|
|
5
|
+
* Every helper in this folder reports failure by returning `false`/`null` and writing a
|
|
6
|
+
* `console.error` — which is why a delete the server refused looked identical to one that
|
|
7
|
+
* worked. Rather than change each helper's signature (and every call site, and every
|
|
8
|
+
* `.then(ok => …)` that depends on the boolean), each failing branch now *also* publishes an
|
|
9
|
+
* `ApiFailure` here. `ApiFailureReporter` subscribes on mount and renders whatever arrives.
|
|
10
|
+
*
|
|
11
|
+
* A module-level bus rather than React context because these fire from plain async functions
|
|
12
|
+
* that have no access to a provider — the same reason crash reporters are built this way.
|
|
13
|
+
*
|
|
14
|
+
* NOTE: nothing published here may contain the API key. The report is written to be pasted
|
|
15
|
+
* into a chat or ticket, so it carries the request *shape* (method, URL, status, response
|
|
16
|
+
* body) but never a credential.
|
|
17
|
+
*/
|
|
18
|
+
export interface ApiFailure {
|
|
19
|
+
/** What the user was trying to do, in their words: "Delete court date". */
|
|
20
|
+
operation: string;
|
|
21
|
+
/** Which record it was, e.g. "#1234 (Negotiations)". */
|
|
22
|
+
subject?: string;
|
|
23
|
+
method?: string;
|
|
24
|
+
url?: string;
|
|
25
|
+
/** `null` when the request never reached the server — offline, DNS, CORS, or a timeout. */
|
|
26
|
+
status: number | null;
|
|
27
|
+
/** One-line plain-English cause, shown to the user. */
|
|
28
|
+
detail: string;
|
|
29
|
+
/** Raw response body (or the thrown error's message), truncated. For the tech team. */
|
|
30
|
+
body?: string;
|
|
31
|
+
at: Date;
|
|
32
|
+
}
|
|
33
|
+
type Listener = (failure: ApiFailure) => void;
|
|
34
|
+
/** Subscribe to API failures. Returns an unsubscribe function suitable for a `useEffect`. */
|
|
35
|
+
export declare function onApiFailure(listener: Listener): () => void;
|
|
36
|
+
/** Publish a failure to every subscriber. A throwing listener must not break the others. */
|
|
37
|
+
export declare function publishApiFailure(failure: ApiFailure): void;
|
|
38
|
+
/** Log and publish a non-2xx response. */
|
|
39
|
+
export declare function reportHttpFailure(operation: string, method: string, url: string, res: Response, subject?: string): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Log and publish a request that never completed.
|
|
42
|
+
*
|
|
43
|
+
* `fetch` *rejects* rather than resolving with `ok: false` when the browser cannot reach the
|
|
44
|
+
* server at all — offline, DNS failure, a CORS preflight refusal, a dropped connection. Those
|
|
45
|
+
* used to escape as unhandled promise rejections from a click handler: no console error, no UI.
|
|
46
|
+
*/
|
|
47
|
+
export declare function reportNetworkFailure(operation: string, method: string, url: string, error: unknown, subject?: string): void;
|
|
48
|
+
/**
|
|
49
|
+
* Publish an application-level problem that is not a single failed request — a partially
|
|
50
|
+
* applied save, for example, where each individual call succeeded or was already reported.
|
|
51
|
+
*/
|
|
52
|
+
export declare function reportProblem(problem: {
|
|
53
|
+
operation: string;
|
|
54
|
+
subject?: string;
|
|
55
|
+
detail: string;
|
|
56
|
+
body?: string;
|
|
57
|
+
}): void;
|
|
58
|
+
/**
|
|
59
|
+
* The copy-paste block handed to the tech team.
|
|
60
|
+
*
|
|
61
|
+
* Written for a chat message or ticket: fixed-width, no markdown, and self-contained — whoever
|
|
62
|
+
* receives it should not have to ask "which record?", "what time?", or "what did the server
|
|
63
|
+
* actually say?". Carries no API key (see the file header).
|
|
64
|
+
*/
|
|
65
|
+
export declare function formatFailureReport(failures: ApiFailure[], context?: {
|
|
66
|
+
activeUser?: number;
|
|
67
|
+
}): string;
|
|
68
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copy text to the clipboard, reporting honestly whether it worked.
|
|
3
|
+
*
|
|
4
|
+
* `navigator.clipboard` is unavailable on insecure origins and *rejects* when the document
|
|
5
|
+
* isn't focused or the permission was denied — so a bare `writeText()` can silently leave the
|
|
6
|
+
* clipboard empty while the UI says "Copied". Both paths are tried and the caller is told
|
|
7
|
+
* which happened, so a failure can fall back to showing the text for manual selection.
|
|
8
|
+
*/
|
|
9
|
+
export declare function copyText(text: string): Promise<boolean>;
|
|
@@ -17,7 +17,8 @@ import { ModalMode } from '../_components/Modal/types';
|
|
|
17
17
|
*
|
|
18
18
|
* @returns
|
|
19
19
|
* - `handleSave` – Validates and persists the edited court date (creates or updates).
|
|
20
|
-
* - `handleDelete` – Confirms, then deletes the selected court date.
|
|
20
|
+
* - `handleDelete` – Confirms, then deletes the selected court date. Returns
|
|
21
|
+
* false and leaves local state untouched if the server refused.
|
|
21
22
|
* - `handleViewUpdateChair` – Optimistically updates a first/second chair in view mode.
|
|
22
23
|
* - `handleSelectedCasesAdjournmentChange` – Adjourns a set of cases (sets AdjournedDate + `OA` determination), then reconciles with the server.
|
|
23
24
|
* - `handleSelectedCasesClearDetermination` – Clears the determination for a set of cases (backend only clears `D`), then reconciles with the server.
|
|
@@ -33,7 +34,7 @@ export declare function useModalActions({ modalMode, selectedCourtDate, selected
|
|
|
33
34
|
pendingNoticeFiles?: File[];
|
|
34
35
|
}): {
|
|
35
36
|
handleSave: () => Promise<boolean>;
|
|
36
|
-
handleDelete: () => Promise<
|
|
37
|
+
handleDelete: () => Promise<boolean>;
|
|
37
38
|
handleViewUpdateChair: (position: "first" | "second", userId: number | null) => void;
|
|
38
39
|
handleSelectedCasesAdjournmentChange: (casesToUpdate: Case[], date: Date | null) => Promise<boolean>;
|
|
39
40
|
handleSelectedCasesClearDetermination: (casesToUpdate: Case[]) => Promise<boolean>;
|