galadrim-feedback 1.0.63 → 1.0.65

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.
Files changed (35) hide show
  1. package/README.md +105 -2
  2. package/bin/cli.js +101 -4
  3. package/dist/assets/icons/info-circle.svg +3 -0
  4. package/dist/index.cjs +472 -41
  5. package/dist/index.mjs +472 -41
  6. package/dist/types/libs/backend-client/api.d.ts +1199 -59
  7. package/dist/types/src/components/molecules/feedbacks/menu/FeedbackDetailsModal.d.ts +12 -3
  8. package/dist/types/src/components/molecules/kanban/LinkToTicketForm.d.ts +1 -1
  9. package/dist/types/src/contexts/feedback/FeedbackProvider.d.ts +2 -1
  10. package/dist/types/src/utils/getGitSha.d.ts +16 -0
  11. package/dist/types/src/utils/getNotionStatusColor.d.ts +1 -0
  12. package/dist/types/src/utils/isolateFromHostApp.d.ts +36 -0
  13. package/index.d.ts +5 -0
  14. package/libs/backend-client/api.ts +2345 -90
  15. package/libs/backend-client/configuration.ts +96 -117
  16. package/next.cjs +24 -0
  17. package/next.d.ts +16 -0
  18. package/package.json +23 -2
  19. package/resolveGitSha.cjs +29 -0
  20. package/src/assets/icons/info-circle.svg +3 -0
  21. package/src/components/boundary/StyleBoundary.tsx +10 -2
  22. package/src/components/molecules/feedbacks/item/FeedbackListItem.tsx +38 -1
  23. package/src/components/molecules/feedbacks/menu/FeedbackDetailsModal.tsx +58 -36
  24. package/src/components/molecules/feedbacks/menu/MenuButton.tsx +44 -2
  25. package/src/components/molecules/feedbacks/shared/FeedbackTextArea.tsx +2 -1
  26. package/src/components/molecules/kanban/LinkToTicketForm.tsx +1 -1
  27. package/src/contexts/feedback/FeedbackProvider.tsx +5 -1
  28. package/src/services/feedback.ts +4 -0
  29. package/src/utils/getGitSha.ts +55 -0
  30. package/src/utils/getNotionStatusColor.ts +16 -0
  31. package/src/utils/isolateFromHostApp.ts +106 -0
  32. package/vite.cjs +29 -0
  33. package/vite.d.ts +23 -0
  34. package/webpack.cjs +28 -0
  35. package/webpack.d.ts +14 -0
package/README.md CHANGED
@@ -47,12 +47,14 @@ Galadrim Feedback requires a plugin to add file path data to your components. We
47
47
  // vite.config.ts
48
48
  import { defineConfig } from "vite";
49
49
  import react from "@vitejs/plugin-react-swc";
50
+ import { includeGitSha } from "galadrim-feedback/vite";
50
51
 
51
52
  export default defineConfig({
52
53
  plugins: [
53
54
  react({
54
55
  plugins: [["swc-plugin-react-generate-paths", {}]],
55
56
  }),
57
+ includeGitSha(),
56
58
  ],
57
59
  });
58
60
  ```
@@ -88,6 +90,7 @@ If your project uses Babel, you can use the Babel plugin instead.
88
90
  // vite.config.ts
89
91
  import { defineConfig } from "vite";
90
92
  import react from "@vitejs/plugin-react";
93
+ import { includeGitSha } from "galadrim-feedback/vite";
91
94
 
92
95
  export default defineConfig({
93
96
  plugins: [
@@ -96,6 +99,7 @@ If your project uses Babel, you can use the Babel plugin instead.
96
99
  plugins: [["babel-plugin-react-generate-paths"]],
97
100
  },
98
101
  }),
102
+ includeGitSha(),
99
103
  ],
100
104
  });
101
105
  ```
@@ -108,7 +112,24 @@ If your project uses Babel, you can use the Babel plugin instead.
108
112
  ```
109
113
 
110
114
 
111
- 3. Configure FeedbackRoot component:
115
+ 3. Configure Git SHA tracking:
116
+ Feedbacks automatically record the git commit SHA of the deployed app — no prop is needed on FeedbackRoot. Pick the integration matching the project's build tool:
117
+ - **Vite**: already handled by the `includeGitSha()` plugin added above (it injects a `<meta name="git-sha">` tag at build time).
118
+ - **Next.js** (webpack or Turbopack): wrap the config in `next.config.js`:
119
+ ```javascript
120
+ const { withGitSha } = require("galadrim-feedback/next");
121
+ module.exports = withGitSha({ /* existing next config */ });
122
+ ```
123
+ (On Vercel this is optional: `NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA` is detected automatically when system environment variables are exposed.)
124
+ - **CRA / custom webpack**: add the webpack plugin (via craco/react-app-rewired for CRA):
125
+ ```javascript
126
+ const GitShaPlugin = require("galadrim-feedback/webpack");
127
+ // in the webpack config: plugins: [new GitShaPlugin()]
128
+ ```
129
+ - **Any other React setup**: add `npx galadrim-feedback inject-git-sha` to the build/deploy script, right after the build — it patches the built HTML files with the `<meta name="git-sha">` tag.
130
+ - **Docker builds**: the .git folder is usually absent from the build context, so pass the SHA explicitly: `docker build --build-arg GIT_SHA=$(git rev-parse HEAD)` with `ARG GIT_SHA` and `ENV GIT_SHA=$GIT_SHA` in the Dockerfile.
131
+
132
+ 4. Configure FeedbackRoot component:
112
133
  - Run `pwd` command in the frontend root directory and use this absolute path for rootDir prop
113
134
  - Detect navigation package used in the project:
114
135
  * If using React Router Dom (react-router-dom):
@@ -139,7 +160,7 @@ If your project uses Babel, you can use the Babel plugin instead.
139
160
  - notionDatabaseId="${NOTION_DATABASE_ID}"
140
161
  * Place it inside the router context but outside main content areas, if needed you can wrap it in a layout component that is parent to the rest of the app
141
162
 
142
- 4. Verification:
163
+ 5. Verification:
143
164
  - Show all modified files
144
165
  - Confirm the navigation setup works with the detected router
145
166
  - List any manual steps needed (like getting projectId from admin) (see https://feedback.galadrim.ovh/admin)
@@ -187,12 +208,14 @@ Galadrim Feedback requires a plugin to add file path data to your components.
187
208
  // vite.config.ts
188
209
  import { defineConfig } from "vite";
189
210
  import react from "@vitejs/plugin-react-swc";
211
+ import { includeGitSha } from "galadrim-feedback/vite";
190
212
 
191
213
  export default defineConfig({
192
214
  plugins: [
193
215
  react({
194
216
  plugins: [["swc-plugin-react-generate-paths", {}]],
195
217
  }),
218
+ includeGitSha(),
196
219
  ],
197
220
  });
198
221
  ```
@@ -240,6 +263,7 @@ If your project uses Babel, you can use the Babel plugin instead.
240
263
  // vite.config.ts
241
264
  import { defineConfig } from "vite";
242
265
  import react from "@vitejs/plugin-react";
266
+ import { includeGitSha } from "galadrim-feedback/vite";
243
267
 
244
268
  export default defineConfig({
245
269
  plugins: [
@@ -248,6 +272,7 @@ If your project uses Babel, you can use the Babel plugin instead.
248
272
  plugins: [["babel-plugin-react-generate-paths"]],
249
273
  },
250
274
  }),
275
+ includeGitSha(),
251
276
  ],
252
277
  });
253
278
  ```
@@ -260,6 +285,10 @@ If your project uses Babel, you can use the Babel plugin instead.
260
285
  }
261
286
  ```
262
287
 
288
+ ### Git SHA / Version Tracking
289
+
290
+ Each feedback records the git commit SHA of the deployed app — see the [Git SHA Setup](#git-sha-setup) section below for the integration matching your build tool.
291
+
263
292
  ### FeedbackRoot Integration
264
293
 
265
294
  Add the **FeedbackRoot** component to the root of your application. It must be placed inside the **router**.
@@ -309,6 +338,80 @@ The kanban integration allows you to link feedback items to tickets/cards in you
309
338
 
310
339
  </details>
311
340
 
341
+ ## Git SHA Setup
342
+
343
+ Each feedback records the git commit SHA of the app it was created on, so it can be traced back to the exact deployed version. Detection is fully automatic — nothing to pass to `FeedbackRoot`. All integrations resolve the SHA the same way: from `GIT_SHA`, `VERCEL_GIT_COMMIT_SHA`, `CF_PAGES_COMMIT_SHA`, `GITHUB_SHA` or `CI_COMMIT_SHA` env vars, falling back to `git rev-parse HEAD`.
344
+
345
+ ### Vite
346
+
347
+ Add the plugin to `vite.config.ts`. It injects a `<meta name="git-sha">` tag at each build (dev server included):
348
+
349
+ ```typescript
350
+ import { includeGitSha } from "galadrim-feedback/vite";
351
+
352
+ export default defineConfig({
353
+ plugins: [react(), includeGitSha()],
354
+ });
355
+ ```
356
+
357
+ ### Next.js
358
+
359
+ Works with webpack and Turbopack — wrap your config; the SHA is exposed as `NEXT_PUBLIC_GIT_SHA` and inlined into the client bundle:
360
+
361
+ ```javascript
362
+ // next.config.js
363
+ const { withGitSha } = require("galadrim-feedback/next");
364
+
365
+ module.exports = withGitSha({
366
+ // your existing next config
367
+ });
368
+ ```
369
+
370
+ On Vercel this is optional: `NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA` is picked up automatically (with "Automatically expose System Environment Variables" enabled).
371
+
372
+ ### CRA / custom webpack
373
+
374
+ Add the webpack plugin (via craco or react-app-rewired for CRA):
375
+
376
+ ```javascript
377
+ const GitShaPlugin = require("galadrim-feedback/webpack");
378
+
379
+ // in the webpack config
380
+ plugins: [new GitShaPlugin()],
381
+ ```
382
+
383
+ ### Any other React setup
384
+
385
+ Run the CLI right after the build; it patches the built HTML files with the `<meta name="git-sha">` tag:
386
+
387
+ ```bash
388
+ npx galadrim-feedback inject-git-sha # auto-detects dist/, build/ or out/
389
+ npx galadrim-feedback inject-git-sha dist # or pass the output dir explicitly
390
+ ```
391
+
392
+ ### Docker builds
393
+
394
+ The `.git` folder is usually absent from the build context, so pass the SHA in explicitly:
395
+
396
+ ```bash
397
+ docker build --build-arg GIT_SHA=$(git rev-parse HEAD) .
398
+ ```
399
+
400
+ ```dockerfile
401
+ ARG GIT_SHA
402
+ ENV GIT_SHA=$GIT_SHA
403
+ ```
404
+
405
+ ### Manual override
406
+
407
+ Expose a `<meta name="git-sha" content="...">` tag or a `window.__GIT_SHA__` global at deploy time, or pass the `gitSha` prop to `FeedbackRoot`.
408
+
409
+ ## Modals and focus traps
410
+
411
+ Galadrim Feedback works on top of modal dialogs (Radix, Headless UI, MUI, react-focus-lock…) without any configuration on your side: you don't need `modal={false}`, `onInteractOutside`, `onOpenAutoFocus` or any other escape hatch on your dialogs.
412
+
413
+ The widget renders in a shadow root and stops its own events from reaching `document`, so the focus traps and "click outside" layers of your app never mistake it for an outside interaction — leaving a feedback on a modal keeps it open and keeps the comment field focusable.
414
+
312
415
  ## Account Creation
313
416
 
314
417
  Once it's installed, you can sign up and then in the Galadmin, you add yourself as a collaborator on the project
package/bin/cli.js CHANGED
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { spawn } from "child_process";
4
+ import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from "fs";
5
+ import { join } from "path";
6
+ import { resolveGitSha } from "../resolveGitSha.cjs";
4
7
 
5
8
  const PROJECT_ID = process.argv
6
9
  .find((arg) => arg.startsWith("--project-id="))
@@ -31,12 +34,14 @@ Galadrim Feedback requires a plugin to add file path data to your components. We
31
34
  // vite.config.ts
32
35
  import { defineConfig } from "vite";
33
36
  import react from "@vitejs/plugin-react-swc";
37
+ import { includeGitSha } from "galadrim-feedback/vite";
34
38
 
35
39
  export default defineConfig({
36
40
  plugins: [
37
41
  react({
38
42
  plugins: [["swc-plugin-react-generate-paths", {}]],
39
43
  }),
44
+ includeGitSha(),
40
45
  ],
41
46
  });
42
47
  \`\`\`
@@ -72,6 +77,7 @@ If your project uses Babel, you can use the Babel plugin instead.
72
77
  // vite.config.ts
73
78
  import { defineConfig } from "vite";
74
79
  import react from "@vitejs/plugin-react";
80
+ import { includeGitSha } from "galadrim-feedback/vite";
75
81
 
76
82
  export default defineConfig({
77
83
  plugins: [
@@ -80,6 +86,7 @@ If your project uses Babel, you can use the Babel plugin instead.
80
86
  plugins: [["babel-plugin-react-generate-paths"]],
81
87
  },
82
88
  }),
89
+ includeGitSha(),
83
90
  ],
84
91
  });
85
92
  \`\`\`
@@ -92,7 +99,24 @@ If your project uses Babel, you can use the Babel plugin instead.
92
99
  \`\`\`
93
100
 
94
101
 
95
- 3. Configure FeedbackRoot component:
102
+ 3. Configure Git SHA tracking:
103
+ Feedbacks automatically record the git commit SHA of the deployed app — no prop is needed on FeedbackRoot. Pick the integration matching the project's build tool:
104
+ - **Vite**: already handled by the \`includeGitSha()\` plugin added above (it injects a \`<meta name="git-sha">\` tag at build time).
105
+ - **Next.js** (webpack or Turbopack): wrap the config in \`next.config.js\`:
106
+ \`\`\`javascript
107
+ const { withGitSha } = require("galadrim-feedback/next");
108
+ module.exports = withGitSha({ /* existing next config */ });
109
+ \`\`\`
110
+ (On Vercel this is optional: \`NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA\` is detected automatically when system environment variables are exposed.)
111
+ - **CRA / custom webpack**: add the webpack plugin (via craco/react-app-rewired for CRA):
112
+ \`\`\`javascript
113
+ const GitShaPlugin = require("galadrim-feedback/webpack");
114
+ // in the webpack config: plugins: [new GitShaPlugin()]
115
+ \`\`\`
116
+ - **Any other React setup**: add \`npx galadrim-feedback inject-git-sha\` to the build/deploy script, right after the build — it patches the built HTML files with the \`<meta name="git-sha">\` tag.
117
+ - **Docker builds**: the .git folder is usually absent from the build context, so pass the SHA explicitly: \`docker build --build-arg GIT_SHA=$(git rev-parse HEAD)\` with \`ARG GIT_SHA\` and \`ENV GIT_SHA=$GIT_SHA\` in the Dockerfile.
118
+
119
+ 4. Configure FeedbackRoot component:
96
120
  - Run \`pwd\` command in the frontend root directory and use this absolute path for rootDir prop
97
121
  - Detect navigation package used in the project:
98
122
  * If using React Router Dom (react-router-dom):
@@ -123,7 +147,7 @@ If your project uses Babel, you can use the Babel plugin instead.
123
147
  - notionDatabaseId="${NOTION_DATABASE_ID}"
124
148
  * Place it inside the router context but outside main content areas, if needed you can wrap it in a layout component that is parent to the rest of the app
125
149
 
126
- 4. Verification:
150
+ 5. Verification:
127
151
  - Show all modified files
128
152
  - Confirm the navigation setup works with the detected router
129
153
  - List any manual steps needed (like getting projectId from admin) (see https://feedback.galadrim.ovh/admin)
@@ -138,15 +162,85 @@ Usage:
138
162
  npx galadrim-feedback <command> [--project-id=<project-id>] [--notion-database-id=<notion-database-id>]
139
163
 
140
164
  Commands:
141
- cursor-init Send the installation prompt directly to Cursor/VS Code
142
- help Show this help message
165
+ cursor-init Send the installation prompt directly to Cursor/VS Code
166
+ inject-git-sha Inject the git commit SHA as <meta name="git-sha"> into
167
+ built HTML files (run after your build, before deploying).
168
+ Optional argument: output dir or HTML file (defaults to
169
+ dist/, build/ or out/)
170
+ help Show this help message
143
171
 
144
172
  Examples:
145
173
  npx galadrim-feedback cursor-init --project-id=<project-id> --notion-database-id=<notion-database-id>
174
+ npx galadrim-feedback inject-git-sha
175
+ npx galadrim-feedback inject-git-sha dist
146
176
  npx galadrim-feedback help
147
177
  `);
148
178
  }
149
179
 
180
+ function collectHtmlFiles(target) {
181
+ if (statSync(target).isFile()) return [target];
182
+ const found = [];
183
+ const walk = (dir) => {
184
+ for (const entry of readdirSync(dir)) {
185
+ if (entry === "node_modules" || entry.startsWith(".")) continue;
186
+ const fullPath = join(dir, entry);
187
+ if (statSync(fullPath).isDirectory()) walk(fullPath);
188
+ else if (entry.endsWith(".html")) found.push(fullPath);
189
+ }
190
+ };
191
+ walk(target);
192
+ return found;
193
+ }
194
+
195
+ function injectMetaTag(html, sha) {
196
+ const meta = `<meta name="git-sha" content="${sha}">`;
197
+ const existing = /<meta\s+name=["']git-sha["'][^>]*\/?>/i;
198
+ if (existing.test(html)) return html.replace(existing, meta);
199
+ if (/<\/head>/i.test(html)) return html.replace(/<\/head>/i, `${meta}</head>`);
200
+ return null;
201
+ }
202
+
203
+ function handleInjectGitSha(targetArg) {
204
+ const sha = resolveGitSha();
205
+ if (!sha) {
206
+ console.error(
207
+ "❌ Could not resolve the git SHA (no CI env var and `git rev-parse HEAD` failed).",
208
+ );
209
+ console.error(
210
+ "💡 In Docker builds, pass it in: --build-arg GIT_SHA=$(git rev-parse HEAD)",
211
+ );
212
+ process.exit(1);
213
+ }
214
+
215
+ const target =
216
+ targetArg || ["dist", "build", "out"].find((dir) => existsSync(dir));
217
+ if (!target || !existsSync(target)) {
218
+ console.error(
219
+ "❌ No build output found (tried dist/, build/, out/). Pass a path: npx galadrim-feedback inject-git-sha <dir-or-file>",
220
+ );
221
+ process.exit(1);
222
+ }
223
+
224
+ const htmlFiles = collectHtmlFiles(target);
225
+ let patched = 0;
226
+ for (const file of htmlFiles) {
227
+ const html = readFileSync(file, "utf8");
228
+ const updated = injectMetaTag(html, sha);
229
+ if (updated && updated !== html) {
230
+ writeFileSync(file, updated);
231
+ patched++;
232
+ }
233
+ }
234
+
235
+ if (patched === 0) {
236
+ console.error(`❌ No HTML file with a </head> tag found under "${target}".`);
237
+ process.exit(1);
238
+ }
239
+ console.log(
240
+ `✅ Injected git-sha ${sha.slice(0, 7)} into ${patched} HTML file(s) under "${target}"`,
241
+ );
242
+ }
243
+
150
244
  function copyToClipboard(text) {
151
245
  return new Promise((resolve, reject) => {
152
246
  let copyCommand;
@@ -227,6 +321,9 @@ function main() {
227
321
  case "cursor-init":
228
322
  handleCursorInit();
229
323
  break;
324
+ case "inject-git-sha":
325
+ handleInjectGitSha(args[1]);
326
+ break;
230
327
  case "help":
231
328
  case "--help":
232
329
  case "-h":
@@ -0,0 +1,3 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M12 16V12M12 8H12.01M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12Z" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
3
+ </svg>