jira-pat 1.0.1 → 1.0.2
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/AGENTS.md +172 -108
- package/README.md +119 -45
- package/backend/__tests__/issues.test.js +69 -56
- package/backend/__tests__/projects.test.js +33 -20
- package/backend/jest.config.js +3 -1
- package/backend/routes/issues.js +28 -0
- package/backend/service/jiraService.js +67 -4
- package/frontend/src/App.jsx +156 -6
- package/frontend/src/__tests__/hooks/useIssueDrawer.test.js +4 -1
- package/frontend/src/__tests__/setup.js +11 -0
- package/frontend/src/components/IssueDetailPanel.jsx +82 -17
- package/frontend/src/components/IssueDrawer.jsx +17 -1
- package/frontend/src/components/IssueTable.jsx +63 -29
- package/frontend/src/components/StandaloneIssuePage.jsx +17 -1
- package/frontend/src/hooks/useIssueDrawer.js +58 -3
- package/frontend/src/index.css +506 -32
- package/frontend/src/services/api.js +10 -0
- package/frontend/src/utils/issueHelpers.jsx +7 -5
- package/package.json +2 -2
- package/.opencode/bun.lock +0 -18
- package/.opencode/package.json +0 -5
package/AGENTS.md
CHANGED
|
@@ -1,118 +1,124 @@
|
|
|
1
1
|
# AGENTS.md - Jira Dashboard
|
|
2
2
|
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
A Jira Dashboard CLI tool with Express backend (port 5000) and React frontend (port 5173).
|
|
6
|
+
|
|
3
7
|
## Project Structure
|
|
4
8
|
|
|
5
9
|
```
|
|
6
10
|
jira-dashboard/
|
|
7
|
-
├── package.json
|
|
8
|
-
├──
|
|
9
|
-
│
|
|
10
|
-
|
|
11
|
-
│ ├──
|
|
12
|
-
│
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
│ │ └── ToastContainer.jsx
|
|
24
|
-
│ └── hooks/ # Custom React hooks
|
|
25
|
-
│ ├── useIssueDrawer.js
|
|
26
|
-
│ ├── useToasts.js
|
|
27
|
-
│ └── useIssuesList.js
|
|
28
|
-
└── vite.config.js
|
|
11
|
+
├── package.json # Root - runs both servers with concurrently
|
|
12
|
+
├── bin/
|
|
13
|
+
│ └── jira.js # CLI entry point for `jira` command
|
|
14
|
+
├── backend/ # Express API (CommonJS), port 5000
|
|
15
|
+
│ ├── index.js # Entry point
|
|
16
|
+
│ ├── routes/ # API route handlers (issues.js, projects.js)
|
|
17
|
+
│ ├── service/ # Jira API integration (jiraService.js)
|
|
18
|
+
│ └── __tests__/ # Jest tests
|
|
19
|
+
└── frontend/ # React app (ES modules + Vite)
|
|
20
|
+
└── src/
|
|
21
|
+
├── App.jsx # Main component
|
|
22
|
+
├── index.css # All styles (~2500 lines)
|
|
23
|
+
├── services/ # API client (api.js)
|
|
24
|
+
├── components/ # React components
|
|
25
|
+
├── hooks/ # Custom React hooks
|
|
26
|
+
└── utils/ # Helper functions
|
|
29
27
|
```
|
|
30
28
|
|
|
31
29
|
## Commands
|
|
32
30
|
|
|
33
31
|
### Development
|
|
34
32
|
```bash
|
|
35
|
-
npm start # Run both backend
|
|
36
|
-
cd frontend && npm run dev # Frontend dev server only
|
|
37
|
-
cd backend && npm start # Backend server only
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### Build & Production
|
|
41
|
-
```bash
|
|
33
|
+
npm start # Run both backend and frontend concurrently
|
|
42
34
|
npm run build # Build frontend for production
|
|
43
|
-
cd frontend && npm run
|
|
44
|
-
cd
|
|
35
|
+
cd frontend && npm run dev # Frontend dev server only (port 5173)
|
|
36
|
+
cd backend && npm start # Backend server only (port 5000)
|
|
45
37
|
```
|
|
46
38
|
|
|
47
39
|
### Testing
|
|
48
40
|
|
|
49
|
-
**Root (runs both
|
|
41
|
+
**Root (runs both):**
|
|
50
42
|
```bash
|
|
51
|
-
npm test # Run all tests
|
|
43
|
+
npm test # Run all tests
|
|
52
44
|
```
|
|
53
45
|
|
|
54
46
|
**Backend (Jest):**
|
|
55
47
|
```bash
|
|
56
|
-
cd backend && npm test
|
|
57
|
-
cd backend && npm test -- --coverage
|
|
58
|
-
cd backend && npm test -- --testPathPattern=
|
|
59
|
-
cd backend && npm test -- --testNamePattern=
|
|
60
|
-
cd backend && npm test -- --
|
|
48
|
+
cd backend && npm test # Watch mode
|
|
49
|
+
cd backend && npm test -- --coverage # With coverage
|
|
50
|
+
cd backend && npm test -- --testPathPattern=routes/issues.test.js # Single file
|
|
51
|
+
cd backend && npm test -- --testNamePattern=create # Tests matching name
|
|
52
|
+
cd backend && npm test -- --watchAll=false # Single run, no watch
|
|
61
53
|
```
|
|
62
54
|
|
|
63
55
|
**Frontend (Vitest):**
|
|
64
56
|
```bash
|
|
65
|
-
cd frontend && npm test
|
|
66
|
-
cd frontend && npm run test:run
|
|
67
|
-
cd frontend && npm test -- src/services/api.test.js #
|
|
68
|
-
cd frontend && npm test -- --grep "should render" #
|
|
69
|
-
cd frontend && npm test -- --coverage
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## Environment Setup
|
|
73
|
-
|
|
74
|
-
Create `/backend/.env`:
|
|
75
|
-
```
|
|
76
|
-
JIRA_BASE_URL=https://your-domain.atlassian.net
|
|
77
|
-
JIRA_EMAIL=your-email@example.com
|
|
78
|
-
JIRA_PAT=your-api-token
|
|
79
|
-
PORT=5000
|
|
80
|
-
BACKEND_BASE_URL=http://localhost:5000
|
|
57
|
+
cd frontend && npm test # Watch mode
|
|
58
|
+
cd frontend && npm run test:run # Single run (CI mode)
|
|
59
|
+
cd frontend && npm test -- src/services/api.test.js # Single file
|
|
60
|
+
cd frontend && npm test -- --grep "should render" # Pattern match
|
|
61
|
+
cd frontend && npm test -- --coverage # With coverage
|
|
81
62
|
```
|
|
82
63
|
|
|
83
|
-
|
|
84
|
-
```
|
|
85
|
-
VITE_API_BASE_URL=http://localhost:5000/api
|
|
86
|
-
```
|
|
64
|
+
---
|
|
87
65
|
|
|
88
|
-
## Code Style
|
|
66
|
+
## Code Style Guidelines
|
|
89
67
|
|
|
90
|
-
### General
|
|
68
|
+
### General Principles
|
|
91
69
|
- No comments unless explaining non-obvious logic
|
|
92
70
|
- Small, focused functions (single responsibility)
|
|
93
71
|
- Prefer early returns to reduce nesting
|
|
94
|
-
-
|
|
95
|
-
|
|
96
|
-
### Frontend (React + Vite - ES Modules)
|
|
97
|
-
- `.jsx` for React components, `.js` for utilities
|
|
98
|
-
- Named exports for utilities, default export for components
|
|
99
|
-
- Functional components with hooks only (no class components)
|
|
100
|
-
- Import order: React → external libs → internal modules → CSS
|
|
72
|
+
- Prefer composition over prop drilling
|
|
73
|
+
- Memoize expensive computations with `useMemo`/`React.memo`
|
|
101
74
|
|
|
75
|
+
### Import Order (Frontend)
|
|
102
76
|
```jsx
|
|
103
77
|
import React, { useState, useEffect } from 'react';
|
|
104
78
|
import { Search, X } from 'lucide-react';
|
|
105
79
|
import { getIssues } from './services/api';
|
|
80
|
+
import { formatDate } from './utils/helpers';
|
|
106
81
|
import './index.css';
|
|
107
82
|
```
|
|
108
83
|
|
|
109
|
-
###
|
|
110
|
-
- Use `
|
|
84
|
+
### React Components
|
|
85
|
+
- Use `.jsx` extension for components, `.js` for utilities
|
|
86
|
+
- Default export for components, named exports for utilities
|
|
87
|
+
- Functional components with hooks only (no class components)
|
|
88
|
+
- Destructure props in function signature
|
|
89
|
+
|
|
90
|
+
```jsx
|
|
91
|
+
// Good
|
|
92
|
+
export default function IssueTable({ issues, onRowClick, loading }) {
|
|
93
|
+
return <table>...</table>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Good - hook pattern
|
|
97
|
+
const [data, setData] = useState(null);
|
|
98
|
+
const isLoading = useMemo(() => expensiveCalculation(data), [data]);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Backend (Node.js)
|
|
102
|
+
- CommonJS: `require()` and `module.exports`
|
|
111
103
|
- Keep routes thin, services thick
|
|
104
|
+
- Always validate input before processing
|
|
105
|
+
- Return appropriate HTTP status codes
|
|
112
106
|
|
|
113
107
|
```javascript
|
|
114
108
|
const express = require('express');
|
|
115
109
|
const router = express.Router();
|
|
110
|
+
|
|
111
|
+
router.get('/:id', async (req, res) => {
|
|
112
|
+
try {
|
|
113
|
+
const data = await service.getData(req.params.id);
|
|
114
|
+
if (!data) return res.status(404).json({ error: 'Not found' });
|
|
115
|
+
res.json(data);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.error('Error:', error.message);
|
|
118
|
+
res.status(500).json({ error: 'Server error', details: error.message });
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
116
122
|
module.exports = router;
|
|
117
123
|
```
|
|
118
124
|
|
|
@@ -121,23 +127,27 @@ module.exports = router;
|
|
|
121
127
|
| Type | Convention | Example |
|
|
122
128
|
|------|------------|---------|
|
|
123
129
|
| Components | PascalCase | `IssueDrawer` |
|
|
130
|
+
| Hooks | camelCase `useXxx` | `useIssueDrawer` |
|
|
131
|
+
| State setters | `setXxx` | `setIssues` |
|
|
124
132
|
| Functions | camelCase | `fetchIssues` |
|
|
125
133
|
| Constants | UPPER_SNAKE | `STATUS_CHIPS` |
|
|
126
|
-
| CSS
|
|
134
|
+
| CSS classes | kebab-case | `.issue-table` |
|
|
127
135
|
| Files | kebab-case | `api-client.js` |
|
|
128
|
-
|
|
|
136
|
+
| Files (components) | PascalCase | `IssueDrawer.jsx` |
|
|
137
|
+
|
|
138
|
+
---
|
|
129
139
|
|
|
130
140
|
## Common Patterns
|
|
131
141
|
|
|
132
142
|
### Debounce (search inputs)
|
|
133
143
|
```jsx
|
|
134
144
|
useEffect(() => {
|
|
135
|
-
const timer = setTimeout(() => fetchData(), 500);
|
|
145
|
+
const timer = setTimeout(() => fetchData(searchQuery), 500);
|
|
136
146
|
return () => clearTimeout(timer);
|
|
137
147
|
}, [searchQuery]);
|
|
138
148
|
```
|
|
139
149
|
|
|
140
|
-
### Async with Loading/Error
|
|
150
|
+
### Async with Loading/Error State
|
|
141
151
|
```jsx
|
|
142
152
|
const [loading, setLoading] = useState(false);
|
|
143
153
|
const [error, setError] = useState(null);
|
|
@@ -170,8 +180,8 @@ const addToast = (message, type = 'info') => {
|
|
|
170
180
|
```jsx
|
|
171
181
|
useEffect(() => {
|
|
172
182
|
const handleKeyDown = (e) => {
|
|
173
|
-
if (e.key === '
|
|
174
|
-
|
|
183
|
+
if (e.key === 'Escape' && !['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)) {
|
|
184
|
+
onClose();
|
|
175
185
|
}
|
|
176
186
|
};
|
|
177
187
|
window.addEventListener('keydown', handleKeyDown);
|
|
@@ -179,67 +189,121 @@ useEffect(() => {
|
|
|
179
189
|
}, []);
|
|
180
190
|
```
|
|
181
191
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
### Backend API Routes
|
|
185
|
-
```javascript
|
|
186
|
-
router.get('/:id', async (req, res) => {
|
|
187
|
-
try {
|
|
188
|
-
const data = await service.getData(req.params.id);
|
|
189
|
-
if (!data) return res.status(404).json({ error: 'Not found' });
|
|
190
|
-
res.json(data);
|
|
191
|
-
} catch (error) {
|
|
192
|
-
console.error('Error:', error.message);
|
|
193
|
-
res.status(500).json({ error: 'Server error', details: error.message });
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
```
|
|
192
|
+
---
|
|
197
193
|
|
|
198
|
-
|
|
199
|
-
```jsx
|
|
200
|
-
{error && (
|
|
201
|
-
<div className="error" role="alert">
|
|
202
|
-
<AlertCircle size={16} />
|
|
203
|
-
{error}
|
|
204
|
-
</div>
|
|
205
|
-
)}
|
|
206
|
-
```
|
|
194
|
+
## Accessibility (A11y)
|
|
207
195
|
|
|
208
|
-
|
|
209
|
-
-
|
|
210
|
-
-
|
|
196
|
+
- Always add `aria-label` to icon-only buttons
|
|
197
|
+
- Use semantic HTML: `<button>`, `<nav>`, `<main>`, `<article>`
|
|
198
|
+
- Add `role="alert"` for error messages
|
|
211
199
|
- Support keyboard navigation (Tab, Enter, Escape, Arrow keys)
|
|
200
|
+
- Add `aria-sort="none/ascending/descending"` to sortable table headers
|
|
201
|
+
- Add `scope="col"` to table headers
|
|
202
|
+
- Wrap pagination in `<nav aria-label="Pagination">`
|
|
212
203
|
|
|
213
204
|
```jsx
|
|
214
205
|
<button onClick={handleDelete} aria-label="Delete item">
|
|
215
206
|
<TrashIcon size={16} />
|
|
216
207
|
</button>
|
|
208
|
+
|
|
209
|
+
<nav aria-label="Pagination">
|
|
210
|
+
<button aria-label="Previous page">Prev</button>
|
|
211
|
+
</nav>
|
|
217
212
|
```
|
|
218
213
|
|
|
214
|
+
---
|
|
215
|
+
|
|
219
216
|
## CSS Guidelines
|
|
220
|
-
|
|
217
|
+
|
|
218
|
+
- Use CSS custom properties (variables) for all colors, spacing, shadows
|
|
221
219
|
- BEM-inspired naming for component styles
|
|
222
220
|
- Avoid inline styles except for dynamic values
|
|
221
|
+
- Group related styles together
|
|
222
|
+
- Use `rem` for sizing, `px` for borders
|
|
223
223
|
|
|
224
224
|
```css
|
|
225
225
|
:root {
|
|
226
226
|
--primary: #0052cc;
|
|
227
|
+
--primary-light: rgba(0, 82, 204, 0.1);
|
|
227
228
|
--spacing-sm: 8px;
|
|
228
229
|
--spacing-md: 16px;
|
|
230
|
+
--radius-md: 4px;
|
|
231
|
+
--transition-fast: 150ms ease;
|
|
229
232
|
}
|
|
230
233
|
|
|
231
|
-
.
|
|
232
|
-
.
|
|
234
|
+
.issue-table { /* Block */ }
|
|
235
|
+
.issue-table__row { /* Element */ }
|
|
236
|
+
.issue-table__row--active { /* Modifier */ }
|
|
233
237
|
```
|
|
234
238
|
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## API Design (Backend)
|
|
242
|
+
|
|
243
|
+
### Response Format
|
|
244
|
+
- Success: `res.json(data)` or `res.status(201).json(data)`
|
|
245
|
+
- Error: `res.status(code).json({ error: 'message', details: error.message })`
|
|
246
|
+
|
|
247
|
+
### Validation
|
|
248
|
+
- Always validate input with regex or type checking
|
|
249
|
+
- Sanitize JQL queries to prevent injection
|
|
250
|
+
- Limit mutation operations with rate limiting
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Testing Guidelines
|
|
255
|
+
|
|
256
|
+
### Backend (Jest + Supertest)
|
|
257
|
+
- Test file location: `__tests__/filename.test.js`
|
|
258
|
+
- Mock external services (axios calls)
|
|
259
|
+
- Use descriptive test names: `it('should return 404 when issue not found')`
|
|
260
|
+
|
|
261
|
+
### Frontend (Vitest + Testing Library)
|
|
262
|
+
- Test file location: `src/__tests__/path/to/file.test.jsx`
|
|
263
|
+
- Test behavior, not implementation
|
|
264
|
+
- Use `screen.getByRole`, `screen.getByText` for queries
|
|
265
|
+
- Mock API calls with `vi.fn()` and `mockResolvedValue`
|
|
266
|
+
|
|
267
|
+
```jsx
|
|
268
|
+
it('should call onRowClick when row is clicked', async () => {
|
|
269
|
+
render(<IssueTable issues={mockIssues} onRowClick={mockFn} />);
|
|
270
|
+
fireEvent.click(screen.getByText('TEST-1'));
|
|
271
|
+
expect(mockFn).toHaveBeenCalledWith('TEST-1');
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Environment Variables
|
|
278
|
+
|
|
279
|
+
### Backend (`backend/.env`)
|
|
280
|
+
```
|
|
281
|
+
JIRA_BASE_URL=https://your-domain.atlassian.net
|
|
282
|
+
JIRA_EMAIL=your-email@example.com
|
|
283
|
+
JIRA_PAT=your-api-token
|
|
284
|
+
PORT=5000
|
|
285
|
+
BACKEND_BASE_URL=http://localhost:5000
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Frontend (`frontend/.env`)
|
|
289
|
+
```
|
|
290
|
+
VITE_API_BASE_URL=http://localhost:5000/api
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
235
295
|
## Jira API Integration
|
|
296
|
+
|
|
236
297
|
- Uses axios with 10-second timeout
|
|
237
298
|
- 60-second in-memory cache (node-cache)
|
|
238
299
|
- Basic Auth with Jira PAT for authentication
|
|
239
|
-
-
|
|
300
|
+
- Jira Cloud API v3 endpoints
|
|
301
|
+
- ADF (Atlassian Document Format) for rich text
|
|
240
302
|
|
|
241
303
|
## Security
|
|
304
|
+
|
|
242
305
|
- Never commit `.env` files (in `.gitignore`)
|
|
243
306
|
- API credentials use Basic Auth with Jira PAT
|
|
244
|
-
- File uploads limited to 10MB
|
|
245
|
-
-
|
|
307
|
+
- File uploads limited to 10MB (multer configuration)
|
|
308
|
+
- Rate limiting on mutation endpoints
|
|
309
|
+
- Input validation and sanitization on all API endpoints
|
package/README.md
CHANGED
|
@@ -2,25 +2,115 @@
|
|
|
2
2
|
|
|
3
3
|
A fast, lightweight, and modern Jira Dashboard built with React, Vite, and Node.js. It avoids CORS and proxy issues by connecting directly to the Jira Cloud API using Basic Authentication within a dedicated Express backend.
|
|
4
4
|
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
1.
|
|
8
|
-
2.
|
|
9
|
-
3.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
1. **Direct Jira Cloud Integration**: Connects to the Jira REST API securely via an Express backend.
|
|
8
|
+
2. **CLI Configuration**: Easy setup with the built-in `jira` CLI tool.
|
|
9
|
+
3. **Dynamic Filtering**: Filter by project, status, or keyword.
|
|
10
|
+
4. **Interactive Issue View**:
|
|
11
|
+
- Full issue details in a side drawer or standalone page.
|
|
12
|
+
- Rich text rendering (Markdown/ADF to HTML).
|
|
13
|
+
- Proxying of Jira-hosted images and attachments.
|
|
14
|
+
- Status transitions and user assignment.
|
|
15
|
+
- File uploads directly to Jira tickets.
|
|
16
|
+
5. **Subtasks & Linked Issues**: Visualize and navigate between related tickets.
|
|
17
|
+
6. **Backend Caching**: 60-second in-memory caching for performance and API rate-limiting compliance.
|
|
18
|
+
7. **Fully Tested**: Comprehensive unit and integration tests for both frontend and backend.
|
|
19
|
+
8. **Error Handling**: Robust error boundaries and toast notifications for a smooth experience.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Getting Started
|
|
24
|
+
|
|
25
|
+
### Prerequisites
|
|
26
|
+
|
|
27
|
+
- Node.js (v18 or higher recommended)
|
|
28
|
+
- An Atlassian account with a Jira Cloud instance
|
|
29
|
+
- A Jira API Token ([Get one here](https://id.atlassian.com/manage-profile/security/api-tokens))
|
|
30
|
+
|
|
31
|
+
### Installation & Setup
|
|
32
|
+
|
|
33
|
+
1. **Download & Install**:
|
|
34
|
+
```bash
|
|
35
|
+
git clone https://github.com/yourusername/jira-dashboard.git
|
|
36
|
+
cd jira-dashboard
|
|
37
|
+
npm install
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
2. **Configure your Account**:
|
|
41
|
+
Run the setup tool to connect your Jira account:
|
|
42
|
+
```bash
|
|
43
|
+
npm link # Optional: allows you to just type 'jira'
|
|
44
|
+
jira config
|
|
45
|
+
```
|
|
46
|
+
Follow the prompts to enter your **Jira URL**, **Email**, and **API Token**.
|
|
47
|
+
|
|
48
|
+
3. **Launch the App**:
|
|
49
|
+
```bash
|
|
50
|
+
npm start
|
|
51
|
+
```
|
|
52
|
+
Your browser should automatically open to `http://localhost:5000`.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Using the Dashboard (User Guide)
|
|
57
|
+
|
|
58
|
+
Once the dashboard is open, here is how you can manage your work:
|
|
59
|
+
|
|
60
|
+
### 1. Finding Your Work
|
|
61
|
+
* **Default View**: When you log in, you will see all issues currently assigned to you.
|
|
62
|
+
* **Search**: Use the search bar at the top to find specific tickets by typing their title or description. (Tip: Press `/` to jump to search).
|
|
63
|
+
* **Filters**: Use the **Project** and **Status** dropdowns to narrow down your list (e.g., only show "In Progress" tasks for project "ABC").
|
|
64
|
+
|
|
65
|
+
### 2. Viewing and Updating Issues
|
|
66
|
+
* **Open Details**: Click on any row in the table. A side panel will slide out with the full description and comments.
|
|
67
|
+
* **Change Status**: Inside the panel, click the status button (like "To Do") to move the ticket to a new stage (like "Done").
|
|
68
|
+
* **Reassign**: Click the user's name or avatar to search for and assign the ticket to someone else.
|
|
69
|
+
* **Add Attachments**: Drag and drop files directly onto the "Upload" area in the side panel to add them to the Jira ticket.
|
|
70
|
+
|
|
71
|
+
### 3. Creating New Issues
|
|
72
|
+
* Click the blue **+** button in the top right corner.
|
|
73
|
+
* Select the **Project** and **Issue Type** (e.g., Task, Bug).
|
|
74
|
+
* Enter a **Summary** and click **Create**. The ticket is instantly added to your Jira instance.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Development (Technical)
|
|
79
|
+
|
|
80
|
+
### Running the Backend (API)
|
|
81
|
+
```bash
|
|
82
|
+
cd backend
|
|
83
|
+
npm start
|
|
84
|
+
```
|
|
85
|
+
The API runs on `http://localhost:5000`.
|
|
86
|
+
|
|
87
|
+
### Running the Frontend (Vite)
|
|
88
|
+
```bash
|
|
89
|
+
cd frontend
|
|
90
|
+
npm run dev
|
|
91
|
+
```
|
|
92
|
+
The frontend runs on `http://localhost:5173` (proxies `/api` to port 5000).
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Testing
|
|
97
|
+
|
|
98
|
+
### Run All Tests
|
|
99
|
+
```bash
|
|
100
|
+
npm test
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Backend Tests
|
|
104
|
+
```bash
|
|
105
|
+
cd backend
|
|
106
|
+
npm test
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Frontend Tests
|
|
110
|
+
```bash
|
|
111
|
+
cd frontend
|
|
112
|
+
npm test
|
|
113
|
+
```
|
|
24
114
|
|
|
25
115
|
---
|
|
26
116
|
|
|
@@ -28,37 +118,21 @@ A fast, lightweight, and modern Jira Dashboard built with React, Vite, and Node.
|
|
|
28
118
|
|
|
29
119
|
```
|
|
30
120
|
jira-dashboard/
|
|
31
|
-
├──
|
|
32
|
-
├── README.md # This file
|
|
33
|
-
│
|
|
121
|
+
├── bin/ # CLI setup and start scripts
|
|
34
122
|
├── backend/ # Node.js + Express API Layer
|
|
35
|
-
│ ├──
|
|
36
|
-
│ ├──
|
|
37
|
-
│
|
|
38
|
-
│ ├── routes/
|
|
39
|
-
│ │ └── issues.js # Route logic for /api/issues
|
|
40
|
-
│ └── service/
|
|
41
|
-
│ └── jiraService.js# Jira REST API communication & JQL construction
|
|
123
|
+
│ ├── routes/ # API Endpoints (Issues, Projects)
|
|
124
|
+
│ ├── service/ # Jira API integration logic
|
|
125
|
+
│ └── __tests__/ # Backend test suite
|
|
42
126
|
│
|
|
43
127
|
└── frontend/ # React + Vite UI
|
|
44
|
-
├──
|
|
45
|
-
├──
|
|
46
|
-
├──
|
|
47
|
-
└──
|
|
48
|
-
├── main.jsx # React DOM entry point
|
|
49
|
-
├── App.jsx # Main Dashboard View and Filters
|
|
50
|
-
├── index.css # Clean, modern UI Styling
|
|
51
|
-
└── services/
|
|
52
|
-
└── api.js # Axios client connecting to backend /api/issues
|
|
128
|
+
├── src/
|
|
129
|
+
│ ├── components/ # React components (Table, Drawer, Modals)
|
|
130
|
+
│ ├── hooks/ # Custom React hooks (Data fetching, UI state)
|
|
131
|
+
│ └── __tests__/ # Frontend test suite
|
|
53
132
|
```
|
|
54
133
|
|
|
55
134
|
---
|
|
56
135
|
|
|
57
|
-
##
|
|
136
|
+
## License
|
|
58
137
|
|
|
59
|
-
|
|
60
|
-
2. Run the application from the root directory:
|
|
61
|
-
```bash
|
|
62
|
-
npm start
|
|
63
|
-
```
|
|
64
|
-
3. Open your browser to `http://localhost:5173`.
|
|
138
|
+
ISC
|