jira-pat 1.0.0 → 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/.github/workflows/publish.yml +31 -0
- package/AGENTS.md +182 -91
- package/README.md +119 -45
- package/backend/__tests__/issues.test.js +69 -56
- package/backend/__tests__/projects.test.js +33 -20
- package/backend/index.js +27 -0
- package/backend/jest.config.js +3 -1
- package/backend/routes/issues.js +29 -2
- package/backend/service/jiraService.js +67 -4
- package/bin/jira.js +89 -32
- package/frontend/src/App.jsx +170 -19
- package/frontend/src/__tests__/hooks/useIssueDrawer.test.js +4 -47
- package/frontend/src/__tests__/setup.js +11 -0
- package/frontend/src/components/CreateIssueModal.jsx +1 -1
- package/frontend/src/components/IssueDetailPanel.jsx +173 -46
- package/frontend/src/components/IssueDrawer.jsx +17 -1
- package/frontend/src/components/IssueTable.jsx +64 -29
- package/frontend/src/components/StandaloneIssuePage.jsx +17 -1
- package/frontend/src/hooks/useIssueDrawer.js +58 -15
- package/frontend/src/index.css +517 -39
- package/frontend/src/services/api.js +11 -1
- package/frontend/src/utils/issueHelpers.jsx +7 -5
- package/package.json +16 -3
- package/backend/.env.example +0 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Publish to NPM
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
# Optional: Also run on manual trigger
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
publish:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Setup Node.js
|
|
17
|
+
uses: actions/setup-node@v4
|
|
18
|
+
with:
|
|
19
|
+
node-version: '22'
|
|
20
|
+
registry-url: 'https://registry.npmjs.org'
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: npm install
|
|
24
|
+
|
|
25
|
+
- name: Run Tests
|
|
26
|
+
run: npm test
|
|
27
|
+
|
|
28
|
+
- name: Publish to NPM
|
|
29
|
+
run: npm publish
|
|
30
|
+
env:
|
|
31
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/AGENTS.md
CHANGED
|
@@ -1,91 +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
|
-
│ └── hooks/ # Custom React hooks
|
|
24
|
-
│ ├── useIssueDrawer.js
|
|
25
|
-
│ ├── useToasts.js
|
|
26
|
-
│ └── useIssuesList.js
|
|
27
|
-
└── 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
|
|
28
27
|
```
|
|
29
28
|
|
|
30
29
|
## Commands
|
|
31
30
|
|
|
31
|
+
### Development
|
|
32
32
|
```bash
|
|
33
|
-
#
|
|
34
|
-
npm
|
|
35
|
-
|
|
36
|
-
#
|
|
37
|
-
cd frontend && npm run dev # Dev server (port 5173)
|
|
38
|
-
cd frontend && npm run build # Production build
|
|
39
|
-
cd frontend && npm run preview # Preview build
|
|
40
|
-
|
|
41
|
-
# Backend
|
|
42
|
-
cd backend && npm start # Start server (port 5000)
|
|
33
|
+
npm start # Run both backend and frontend concurrently
|
|
34
|
+
npm run build # Build frontend for production
|
|
35
|
+
cd frontend && npm run dev # Frontend dev server only (port 5173)
|
|
36
|
+
cd backend && npm start # Backend server only (port 5000)
|
|
43
37
|
```
|
|
44
38
|
|
|
45
|
-
|
|
39
|
+
### Testing
|
|
46
40
|
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
JIRA_EMAIL=your-email@example.com
|
|
51
|
-
JIRA_PAT=your-api-token
|
|
52
|
-
PORT=5000
|
|
53
|
-
BACKEND_BASE_URL=http://localhost:5000
|
|
41
|
+
**Root (runs both):**
|
|
42
|
+
```bash
|
|
43
|
+
npm test # Run all tests
|
|
54
44
|
```
|
|
55
45
|
|
|
56
|
-
|
|
46
|
+
**Backend (Jest):**
|
|
47
|
+
```bash
|
|
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
|
|
57
53
|
```
|
|
58
|
-
|
|
54
|
+
|
|
55
|
+
**Frontend (Vitest):**
|
|
56
|
+
```bash
|
|
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
|
|
59
62
|
```
|
|
60
63
|
|
|
61
|
-
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Code Style Guidelines
|
|
62
67
|
|
|
63
|
-
### General
|
|
68
|
+
### General Principles
|
|
64
69
|
- No comments unless explaining non-obvious logic
|
|
65
70
|
- Small, focused functions (single responsibility)
|
|
66
71
|
- Prefer early returns to reduce nesting
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
### Frontend (React + Vite - ES Modules)
|
|
70
|
-
- `.jsx` for React components, `.js` for utilities
|
|
71
|
-
- Named exports for utilities, default export for components
|
|
72
|
-
- Functional components with hooks only (no class components)
|
|
73
|
-
- Import order: React → external libs → internal modules → CSS
|
|
72
|
+
- Prefer composition over prop drilling
|
|
73
|
+
- Memoize expensive computations with `useMemo`/`React.memo`
|
|
74
74
|
|
|
75
|
+
### Import Order (Frontend)
|
|
75
76
|
```jsx
|
|
76
77
|
import React, { useState, useEffect } from 'react';
|
|
77
78
|
import { Search, X } from 'lucide-react';
|
|
78
79
|
import { getIssues } from './services/api';
|
|
80
|
+
import { formatDate } from './utils/helpers';
|
|
79
81
|
import './index.css';
|
|
80
82
|
```
|
|
81
83
|
|
|
82
|
-
###
|
|
83
|
-
- 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`
|
|
84
103
|
- Keep routes thin, services thick
|
|
104
|
+
- Always validate input before processing
|
|
105
|
+
- Return appropriate HTTP status codes
|
|
85
106
|
|
|
86
107
|
```javascript
|
|
87
108
|
const express = require('express');
|
|
88
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
|
+
|
|
89
122
|
module.exports = router;
|
|
90
123
|
```
|
|
91
124
|
|
|
@@ -94,23 +127,27 @@ module.exports = router;
|
|
|
94
127
|
| Type | Convention | Example |
|
|
95
128
|
|------|------------|---------|
|
|
96
129
|
| Components | PascalCase | `IssueDrawer` |
|
|
130
|
+
| Hooks | camelCase `useXxx` | `useIssueDrawer` |
|
|
131
|
+
| State setters | `setXxx` | `setIssues` |
|
|
97
132
|
| Functions | camelCase | `fetchIssues` |
|
|
98
133
|
| Constants | UPPER_SNAKE | `STATUS_CHIPS` |
|
|
99
|
-
| CSS
|
|
134
|
+
| CSS classes | kebab-case | `.issue-table` |
|
|
100
135
|
| Files | kebab-case | `api-client.js` |
|
|
101
|
-
|
|
|
136
|
+
| Files (components) | PascalCase | `IssueDrawer.jsx` |
|
|
137
|
+
|
|
138
|
+
---
|
|
102
139
|
|
|
103
140
|
## Common Patterns
|
|
104
141
|
|
|
105
142
|
### Debounce (search inputs)
|
|
106
143
|
```jsx
|
|
107
144
|
useEffect(() => {
|
|
108
|
-
const timer = setTimeout(() => fetchData(), 500);
|
|
145
|
+
const timer = setTimeout(() => fetchData(searchQuery), 500);
|
|
109
146
|
return () => clearTimeout(timer);
|
|
110
147
|
}, [searchQuery]);
|
|
111
148
|
```
|
|
112
149
|
|
|
113
|
-
### Async with Loading/Error
|
|
150
|
+
### Async with Loading/Error State
|
|
114
151
|
```jsx
|
|
115
152
|
const [loading, setLoading] = useState(false);
|
|
116
153
|
const [error, setError] = useState(null);
|
|
@@ -143,8 +180,8 @@ const addToast = (message, type = 'info') => {
|
|
|
143
180
|
```jsx
|
|
144
181
|
useEffect(() => {
|
|
145
182
|
const handleKeyDown = (e) => {
|
|
146
|
-
if (e.key === '
|
|
147
|
-
|
|
183
|
+
if (e.key === 'Escape' && !['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)) {
|
|
184
|
+
onClose();
|
|
148
185
|
}
|
|
149
186
|
};
|
|
150
187
|
window.addEventListener('keydown', handleKeyDown);
|
|
@@ -152,67 +189,121 @@ useEffect(() => {
|
|
|
152
189
|
}, []);
|
|
153
190
|
```
|
|
154
191
|
|
|
155
|
-
|
|
192
|
+
---
|
|
156
193
|
|
|
157
|
-
|
|
158
|
-
```javascript
|
|
159
|
-
router.get('/:id', async (req, res) => {
|
|
160
|
-
try {
|
|
161
|
-
const data = await service.getData(req.params.id);
|
|
162
|
-
if (!data) return res.status(404).json({ error: 'Not found' });
|
|
163
|
-
res.json(data);
|
|
164
|
-
} catch (error) {
|
|
165
|
-
console.error('Error:', error.message);
|
|
166
|
-
res.status(500).json({ error: 'Server error', details: error.message });
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
```
|
|
194
|
+
## Accessibility (A11y)
|
|
170
195
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
<div className="error" role="alert">
|
|
175
|
-
<AlertCircle size={16} />
|
|
176
|
-
{error}
|
|
177
|
-
</div>
|
|
178
|
-
)}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
## Accessibility
|
|
182
|
-
- Always use `aria-label` on icon-only buttons
|
|
183
|
-
- Use semantic HTML (`<button>`, `<nav>`, `<main>`)
|
|
196
|
+
- Always add `aria-label` to icon-only buttons
|
|
197
|
+
- Use semantic HTML: `<button>`, `<nav>`, `<main>`, `<article>`
|
|
198
|
+
- Add `role="alert"` for error messages
|
|
184
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">`
|
|
185
203
|
|
|
186
204
|
```jsx
|
|
187
205
|
<button onClick={handleDelete} aria-label="Delete item">
|
|
188
206
|
<TrashIcon size={16} />
|
|
189
207
|
</button>
|
|
208
|
+
|
|
209
|
+
<nav aria-label="Pagination">
|
|
210
|
+
<button aria-label="Previous page">Prev</button>
|
|
211
|
+
</nav>
|
|
190
212
|
```
|
|
191
213
|
|
|
214
|
+
---
|
|
215
|
+
|
|
192
216
|
## CSS Guidelines
|
|
193
|
-
|
|
217
|
+
|
|
218
|
+
- Use CSS custom properties (variables) for all colors, spacing, shadows
|
|
194
219
|
- BEM-inspired naming for component styles
|
|
195
220
|
- Avoid inline styles except for dynamic values
|
|
221
|
+
- Group related styles together
|
|
222
|
+
- Use `rem` for sizing, `px` for borders
|
|
196
223
|
|
|
197
224
|
```css
|
|
198
225
|
:root {
|
|
199
226
|
--primary: #0052cc;
|
|
227
|
+
--primary-light: rgba(0, 82, 204, 0.1);
|
|
200
228
|
--spacing-sm: 8px;
|
|
201
229
|
--spacing-md: 16px;
|
|
230
|
+
--radius-md: 4px;
|
|
231
|
+
--transition-fast: 150ms ease;
|
|
202
232
|
}
|
|
203
233
|
|
|
204
|
-
.
|
|
205
|
-
.
|
|
234
|
+
.issue-table { /* Block */ }
|
|
235
|
+
.issue-table__row { /* Element */ }
|
|
236
|
+
.issue-table__row--active { /* Modifier */ }
|
|
237
|
+
```
|
|
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
|
+
});
|
|
206
273
|
```
|
|
207
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
|
+
|
|
208
295
|
## Jira API Integration
|
|
296
|
+
|
|
209
297
|
- Uses axios with 10-second timeout
|
|
210
298
|
- 60-second in-memory cache (node-cache)
|
|
211
299
|
- Basic Auth with Jira PAT for authentication
|
|
212
|
-
-
|
|
300
|
+
- Jira Cloud API v3 endpoints
|
|
301
|
+
- ADF (Atlassian Document Format) for rich text
|
|
213
302
|
|
|
214
303
|
## Security
|
|
304
|
+
|
|
215
305
|
- Never commit `.env` files (in `.gitignore`)
|
|
216
306
|
- API credentials use Basic Auth with Jira PAT
|
|
217
|
-
- File uploads limited to 10MB
|
|
218
|
-
-
|
|
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
|