@wasilabsoftware/jira-extension-plugin-react
Version:
React wrapper components for jira-extension-plugin web components
244 lines (190 loc) • 7.52 kB
Markdown
# @wasilabsoftware/jira-extension-plugin-react
React wrapper components for [jira-extension-plugin](https://www.npmjs.com/package/jira-extension-plugin). These components provide full TypeScript support and React-friendly event bindings.
## Installation
```bash
npm install @wasilabsoftware/@wasilabsoftware/jira-extension-plugin-react
```
This will automatically install:
- `jira-extension-plugin` (core web components)
- `@stencil/react-output-target` (React runtime)
### Using with Next.js?
See the [Next.js Usage Guide](NEXTJS.md) for specific Next.js setup instructions and examples.
## Requirements
- React >= 17.0.0
- TypeScript >= 5.0.0 (for TypeScript projects)
## Usage
### Basic Example
```tsx
import { JiraDashboard } from '@wasilabsoftware/jira-extension-plugin-react';
function App() {
return (
<JiraDashboard
jiraDomain="https://your-domain.atlassian.net"
jiraEmail="user@example.com"
jiraToken="your-jira-token"
apiToken="your-api-token"
apiBaseUrl="https://your-api.workers.dev"
projectKey="VINM"
boardId="123"
initialView="backlog"
/>
);
}
```
### Event Handling
Events are exposed as React props with the `on` prefix:
```tsx
import { JiraIssueTable } from '@wasilabsoftware/jira-extension-plugin-react';
function IssueList() {
const handleIssueSelected = (event: CustomEvent) => {
console.log('Selected issue:', event.detail.issueKey);
// Navigate to issue detail page, etc.
};
const handleCreateClick = () => {
console.log('Create button clicked');
};
return (
<JiraIssueTable
jiraDomain="https://your-domain.atlassian.net"
jiraEmail="user@example.com"
jiraToken="your-jira-token"
apiToken="your-api-token"
apiBaseUrl="https://your-api.workers.dev"
projectKey="VINM"
sprintType="backlog"
onIssueSelected={handleIssueSelected}
onCreateIssueClick={handleCreateClick}
/>
);
}
```
## Available Components
All components from `jira-extension-plugin` are available as React components:
### Main Components
- **`<JiraDashboard>`** - Complete dashboard with navigation
- **`<JiraIssueTable>`** - Sortable table of issues
- **`<JiraIssueDetail>`** - Detailed issue view with comments
- **`<JiraCreateIssue>`** - Form to create new issues
- **`<JiraEditIssue>`** - Form to edit existing issues
### UI Components
- **`<JiraAvatar>`** - User avatar display
- **`<JiraStatusBadge>`** - Status indicator
- **`<JiraPriorityBadge>`** - Priority indicator
- **`<JiraSpinner>`** - Loading spinner
- **`<JiraError>`** - Error display
## Props
### JiraDashboard
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `jiraDomain` | `string` | ✅ | Your Jira domain (e.g., `https://yourcompany.atlassian.net`) |
| `jiraEmail` | `string` | ✅ | Email associated with your Jira account |
| `jiraToken` | `string` | ✅ | Jira API token |
| `apiToken` | `string` | ✅ | External API token |
| `apiBaseUrl` | `string` | ✅ | Base URL of your API |
| `projectKey` | `string` | ✅ | Jira project key (e.g., "VINM") |
| `boardId` | `string` | ❌ | Board ID for sprint view |
| `initialView` | `'backlog' \| 'current-sprint' \| 'all'` | ❌ | Initial view (default: 'backlog') |
### JiraIssueTable
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `jiraDomain` | `string` | ✅ | Your Jira domain |
| `jiraEmail` | `string` | ✅ | Email address |
| `jiraToken` | `string` | ✅ | Jira API token |
| `apiToken` | `string` | ✅ | External API token |
| `apiBaseUrl` | `string` | ✅ | API base URL |
| `projectKey` | `string` | ✅ | Jira project key |
| `sprintType` | `'backlog' \| 'current-sprint' \| 'all'` | ❌ | Issue filter (default: 'backlog') |
| `boardId` | `string` | ❌ | Required for 'current-sprint' |
| `maxResults` | `number` | ❌ | Max issues to fetch (default: 50) |
| `onIssueSelected` | `(event: CustomEvent) => void` | ❌ | Fired when issue is clicked |
| `onCreateIssueClick` | `() => void` | ❌ | Fired when create button clicked |
| `onLoadError` | `(event: CustomEvent) => void` | ❌ | Fired on load errors |
### JiraIssueDetail
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `jiraDomain` | `string` | ✅ | Your Jira domain |
| `jiraEmail` | `string` | ✅ | Email address |
| `jiraToken` | `string` | ✅ | Jira API token |
| `apiToken` | `string` | ✅ | External API token |
| `apiBaseUrl` | `string` | ✅ | API base URL |
| `issueKey` | `string` | ✅ | Issue key (e.g., "VINM-123") |
| `editable` | `boolean` | ❌ | Show edit button (default: true) |
| `onEditClick` | `() => void` | ❌ | Fired when edit button clicked |
| `onCloseClick` | `() => void` | ❌ | Fired when close button clicked |
| `onStatusChanged` | `(event: CustomEvent) => void` | ❌ | Fired when status changes |
| `onLoadError` | `(event: CustomEvent) => void` | ❌ | Fired on load errors |
## TypeScript Support
All components are fully typed with TypeScript definitions included. You'll get autocomplete and type checking for all props and events.
```tsx
import { JiraDashboard } from '@wasilabsoftware/jira-extension-plugin-react';
import type { IssueSelectedEventDetail } from '@wasilabsoftware/jira-extension-plugin-react';
function App() {
const handleIssueSelected = (event: CustomEvent<IssueSelectedEventDetail>) => {
const { issueKey } = event.detail; // Fully typed!
};
return (
<JiraDashboard
jiraDomain="https://example.atlassian.net"
// TypeScript will enforce required props and validate types
onIssueSelected={handleIssueSelected}
/>
);
}
```
## Styling
The components use CSS custom properties for theming. You can override these in your global CSS:
```css
:root {
--jira-color-primary: #0052cc;
--jira-color-text-primary: #172b4d;
--jira-font-family: 'Your Font', sans-serif;
}
```
See the [main package](https://www.npmjs.com/package/jira-extension-plugin) for all available CSS variables.
## Example: Complete Integration
```tsx
import React, { useState } from 'react';
import {
JiraDashboard,
JiraIssueTable,
JiraIssueDetail
} from '@wasilabsoftware/jira-extension-plugin-react';
function JiraApp() {
const [view, setView] = useState<'list' | 'detail'>('list');
const [selectedIssue, setSelectedIssue] = useState<string | null>(null);
const authProps = {
jiraDomain: process.env.REACT_APP_JIRA_DOMAIN!,
jiraEmail: process.env.REACT_APP_JIRA_EMAIL!,
jiraToken: process.env.REACT_APP_JIRA_TOKEN!,
apiToken: process.env.REACT_APP_API_TOKEN!,
apiBaseUrl: process.env.REACT_APP_API_BASE_URL!,
};
if (view === 'detail' && selectedIssue) {
return (
<JiraIssueDetail
{...authProps}
issueKey={selectedIssue}
onCloseClick={() => setView('list')}
/>
);
}
return (
<JiraIssueTable
{...authProps}
projectKey="VINM"
sprintType="backlog"
onIssueSelected={(e) => {
setSelectedIssue(e.detail.issueKey);
setView('detail');
}}
/>
);
}
export default JiraApp;
```
## API Requirements
This library requires a backend API proxy for Jira API calls. See the [jira-extension-plugin documentation](https://www.npmjs.com/package/jira-extension-plugin) for API setup instructions.
## Related Packages
- [jira-extension-plugin](https://www.npmjs.com/package/jira-extension-plugin) - Core web components (framework-agnostic)
## License
MIT