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
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/App.tsx b/src/App.tsx
index 3e92318..9423135 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -143,7 +143,10 @@ function App() {
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 })}
+
+ />
+
{
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);
@@ -221,7 +224,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"
>
-
+
)}
@@ -284,6 +287,17 @@ export const TicketItem = ({
Log
+
+
+
)}
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/src/lib/jira.ts b/src/lib/jira.ts
index 20c59e1..4e62499 100644
--- a/src/lib/jira.ts
+++ b/src/lib/jira.ts
@@ -1,10 +1,16 @@
import type { AppSettings, JiraTicket } from "./types";
const createHeaders = (settings: AppSettings) => {
+ // 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[];
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),
+ },
})