From cd656765466ff5ba7959136e9080d95bada11b37 Mon Sep 17 00:00:00 2001 From: Bernhard Dorn Date: Thu, 8 Jan 2026 17:42:31 +0100 Subject: [PATCH 1/5] feat: adding email for jira auth to settings --- manifest.json | 2 +- package.json | 4 ++-- src/components/Settings.tsx | 21 ++++++++++++++++++--- src/lib/jira.ts | 8 +++++++- src/lib/storage.ts | 3 ++- src/lib/types.ts | 1 + 6 files changed, 31 insertions(+), 8 deletions(-) diff --git a/manifest.json b/manifest.json index 69847d5..b3424ec 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "JiraTime", - "version": "1.2.2", + "version": "1.3.0", "description": "Simple Jira Time Tracking for Developers. By yours truly Bernhard Dorn.", "author": "Bernhard Dorn", "action": { diff --git a/package.json b/package.json index 18409e1..41370bd 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jiratime", "private": true, - "version": "0.0.0", + "version": "1.3.0", "type": "module", "scripts": { "dev": "vite", @@ -35,4 +35,4 @@ "typescript-eslint": "^8.46.4", "vite": "^7.2.4" } -} +} \ No newline at end of file diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index a9cee33..fa57a79 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -16,6 +16,7 @@ export const Settings = ({ onSave, onCancel, showCancel, onThemeChange }: Settin // Initialize formData with default values. The useEffect hook will load actual settings. const [formData, setFormData] = useState>({ jiraHost: "", + jiraEmail: "", jiraPat: "", theme: "system", // Default theme }); @@ -37,8 +38,13 @@ export const Settings = ({ onSave, onCancel, showCancel, onThemeChange }: Settin try { // Basic validation - if (!formData.jiraHost || !formData.jiraPat) { - throw new Error("All fields are required"); + if (!formData.jiraHost || !formData.jiraPat || !formData.jiraEmail) { + throw new Error("Host, Email and PAT fields are required"); + } + + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!emailRegex.test(formData.jiraEmail)) { + throw new Error("Invalid email format"); } let host = formData.jiraHost.trim(); @@ -51,7 +57,8 @@ export const Settings = ({ onSave, onCancel, showCancel, onThemeChange }: Settin const cleanSettings: AppSettings = { jiraHost: host, - jiraPat: formData.jiraPat.trim(), + jiraEmail: formData.jiraEmail?.trim() || "", + jiraPat: formData.jiraPat.trim() || "", theme: (formData.theme as 'light' | 'dark' | 'system') || 'system', pinnedTicketKeys: formData.pinnedTicketKeys || [], filterStatuses: formData.filterStatuses?.trim() || "", @@ -109,6 +116,14 @@ export const Settings = ({ onSave, onCancel, showCancel, onThemeChange }: Settin + setFormData({ ...formData, jiraEmail: e.target.value })} + + /> + { + // Jira Cloud requires Basic Auth with email:token + // Jira Server/DC uses Bearer token (PAT) + const auth = settings.jiraEmail + ? `Basic ${btoa(`${settings.jiraEmail}:${settings.jiraPat}`)}` + : `Bearer ${settings.jiraPat}`; + const headers: HeadersInit = { "Content-Type": "application/json", "Accept": "application/json", - "Authorization": `Bearer ${settings.jiraPat}` + "Authorization": auth }; return headers; }; diff --git a/src/lib/storage.ts b/src/lib/storage.ts index 6b2f2ed..ca443e2 100644 --- a/src/lib/storage.ts +++ b/src/lib/storage.ts @@ -5,10 +5,11 @@ export const saveSettings = async (settings: AppSettings): Promise => { }; export const getSettings = async (): Promise => { - const result = await chrome.storage.sync.get(["jiraHost", "jiraPat", "theme", "pinnedTicketKeys", "filterStatuses", "filterIssueTypes"]); + const result = await chrome.storage.sync.get(["jiraHost", "jiraEmail", "jiraPat", "theme", "pinnedTicketKeys", "filterStatuses", "filterIssueTypes"]); if (result.jiraHost && result.jiraPat) { return { jiraHost: result.jiraHost as string, + jiraEmail: (result.jiraEmail as string) || "", jiraPat: result.jiraPat as string, theme: (result.theme as 'light' | 'dark' | 'system') || 'system', pinnedTicketKeys: (result.pinnedTicketKeys as string[]) || [], diff --git a/src/lib/types.ts b/src/lib/types.ts index b0a49cc..9161cae 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -1,5 +1,6 @@ export interface AppSettings { jiraHost: string; + jiraEmail: string; jiraPat: string; theme: 'light' | 'dark' | 'system'; pinnedTicketKeys: string[]; From 92469ce980c31f51b4eb3b1901c98cf5eb348b4c Mon Sep 17 00:00:00 2001 From: Bernhard Dorn Date: Thu, 8 Jan 2026 17:49:20 +0100 Subject: [PATCH 2/5] feat: added link to github issues --- src/App.tsx | 5 ++++- src/global.d.ts | 3 +++ vite.config.ts | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 src/global.d.ts diff --git a/src/App.tsx b/src/App.tsx index 3e92318..9423135 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -143,7 +143,10 @@ function App() {

JiraTime

-

v1.2.0

+

v{__APP_VERSION__}

+

+ Found a bug? Report an issue +

diff --git a/src/global.d.ts b/src/global.d.ts new file mode 100644 index 0000000..dbb4c62 --- /dev/null +++ b/src/global.d.ts @@ -0,0 +1,3 @@ +/// + +declare const __APP_VERSION__: string; diff --git a/vite.config.ts b/vite.config.ts index 30293ff..72695ad 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -9,4 +9,7 @@ export default defineConfig({ react(), crx({ manifest: manifest as any }), ], + define: { + '__APP_VERSION__': JSON.stringify(manifest.version), + }, }) From ec6a6f01a47658a29a215c36b732fb60f154a452 Mon Sep 17 00:00:00 2001 From: Bernhard Dorn Date: Thu, 8 Jan 2026 18:19:00 +0100 Subject: [PATCH 3/5] ci: restrict Pull Requests to only foreigners. --- .github/workflows/no-prs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/no-prs.yml b/.github/workflows/no-prs.yml index b8a752e..ca7257e 100644 --- a/.github/workflows/no-prs.yml +++ b/.github/workflows/no-prs.yml @@ -11,6 +11,7 @@ permissions: jobs: close-pr: runs-on: ubuntu-latest + if: github.actor != github.repository_owner && github.actor != 'github-copilot[bot]' && github.actor != 'copilot-workspace[bot]' steps: - name: Close Pull Request uses: actions/github-script@v7 From 884a29bac323f0780492dc8c0deaeabce2420444 Mon Sep 17 00:00:00 2001 From: Bernhard Dorn Date: Thu, 8 Jan 2026 18:26:51 +0100 Subject: [PATCH 4/5] fix: pinned icon changed from trash can to pinoff --- src/components/TicketItem.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/TicketItem.tsx b/src/components/TicketItem.tsx index 421c965..22ecec0 100644 --- a/src/components/TicketItem.tsx +++ b/src/components/TicketItem.tsx @@ -6,9 +6,9 @@ import { formatDuration, formatDurationFromStart, parseDuration, cn } from "../l import { Button } from "./ui/Button"; import { Input } from "./ui/Input"; import { - Trash2, Play, Square, ExternalLink, ChevronDown, ChevronUp, Clock, + Play, Square, ExternalLink, ChevronDown, ChevronUp, Clock, Bug, CheckSquare, Bookmark, Zap, GitCommit, FileQuestion, - HelpCircle, Microscope + HelpCircle, Microscope, PinOff } from "lucide-react"; // Helper for Issue Type Icon @@ -221,7 +221,7 @@ export const TicketItem = ({ className="p-1.5 text-gray-400 hover:text-red-600 dark:hover:text-red-400 dark:text-gray-500 transition-colors rounded-full hover:bg-red-50 dark:hover:bg-red-900/20" title="Unpin Ticket" > - + )}
From c099cb39213554ed392f79aa68a688d13357b945 Mon Sep 17 00:00:00 2001 From: Bernhard Dorn Date: Thu, 8 Jan 2026 18:48:33 +0100 Subject: [PATCH 5/5] feat: #1 added Work description input --- src/components/TicketItem.tsx | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/components/TicketItem.tsx b/src/components/TicketItem.tsx index 22ecec0..e430252 100644 --- a/src/components/TicketItem.tsx +++ b/src/components/TicketItem.tsx @@ -77,6 +77,7 @@ export const TicketItem = ({ }: TicketItemProps) => { const [isExpanded, setIsExpanded] = useState(false); const [manualTime, setManualTime] = useState(""); + const [description, setDescription] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); const [liveDuration, setLiveDuration] = useState(""); @@ -118,8 +119,9 @@ export const TicketItem = ({ checkTouchGrass(seconds); } - await addWorklog(settings, ticket.id, manualTime); + await addWorklog(settings, ticket.id, manualTime, description); setManualTime(""); + setDescription(""); onRefresh(); // Optional: Show success feedback } catch (error) { @@ -146,8 +148,9 @@ export const TicketItem = ({ seconds = 60; } - await addWorklog(settings, ticket.id, seconds); + await addWorklog(settings, ticket.id, seconds, description); onStopTimer(); + setDescription(""); onRefresh(); } catch (error) { console.error(error); @@ -284,6 +287,17 @@ export const TicketItem = ({ Log + +
+