refactor(viz-platform): extract skills and slim commands
Extract shared knowledge from 10 commands into 7 reusable skills: - mcp-tools-reference.md: All viz-platform MCP tool signatures - theming-system.md: Theme tokens, CSS variables, color palettes - accessibility-rules.md: WCAG contrast, color-blind safe palettes - dmc-components.md: DMC categories, validation, common props - responsive-design.md: Breakpoints, mobile-first, grid config - chart-types.md: Plotly chart types, export formats, resolution - layout-templates.md: Dashboard templates, filter types All commands now reference skills via "Skills to Load" section. Commands reduced from 1396 lines total to 427 lines (69% reduction). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
64
plugins/viz-platform/skills/accessibility-rules.md
Normal file
64
plugins/viz-platform/skills/accessibility-rules.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# Accessibility Rules
|
||||
|
||||
## WCAG Contrast Standards
|
||||
|
||||
| Level | Ratio | Use Case |
|
||||
|-------|-------|----------|
|
||||
| AA (normal text) | 4.5:1 | Body text, labels |
|
||||
| AA (large text) | 3:1 | Headings, 14pt+ bold |
|
||||
| AAA (enhanced) | 7:1 | Highest accessibility |
|
||||
|
||||
## Color Blindness Types
|
||||
|
||||
| Type | Affected Colors | Population |
|
||||
|------|-----------------|------------|
|
||||
| **Deuteranopia** | Red-Green (green-blind) | ~6% males, 0.4% females |
|
||||
| **Protanopia** | Red-Green (red-blind) | ~2.5% males, 0.05% females |
|
||||
| **Tritanopia** | Blue-Yellow | ~0.01% total |
|
||||
|
||||
## Color-Blind Safe Palettes
|
||||
|
||||
### IBM Design Colors
|
||||
```
|
||||
#648FFF #785EF0 #DC267F #FE6100 #FFB000
|
||||
```
|
||||
|
||||
### Tableau Colorblind 10
|
||||
```
|
||||
#006BA4 #FF800E #ABABAB #595959 #5F9ED1
|
||||
#C85200 #898989 #A2C8EC #FFBC79 #CFCFCF
|
||||
```
|
||||
|
||||
### Okabe-Ito
|
||||
```
|
||||
#E69F00 #56B4E9 #009E73 #F0E442 #0072B2
|
||||
#D55E00 #CC79A7 #000000
|
||||
```
|
||||
|
||||
### Safe Palette Categories
|
||||
|
||||
```json
|
||||
{
|
||||
"categorical": ["#4477AA", "#EE6677", "#228833", "#CCBB44", "#66CCEE", "#AA3377", "#BBBBBB"],
|
||||
"sequential": ["#FEE0D2", "#FC9272", "#DE2D26"],
|
||||
"diverging": ["#4575B4", "#FFFFBF", "#D73027"]
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Don't rely on color alone** - Use shapes, patterns, or labels
|
||||
2. **Test with simulation** - View through color blindness simulators
|
||||
3. **Use sufficient contrast** - Minimum 4.5:1 for text, 3:1 for large elements
|
||||
4. **Limit color count** - Fewer colors = easier to distinguish
|
||||
5. **Use semantic colors** - Blue for information, red for errors (with icons)
|
||||
|
||||
## Accessibility Scoring
|
||||
|
||||
| Grade | Description |
|
||||
|-------|-------------|
|
||||
| A | Excellent - All WCAG AAA standards met |
|
||||
| B | Good - WCAG AA standards met with minor warnings |
|
||||
| C | Acceptable - WCAG AA met but improvements recommended |
|
||||
| D | Poor - Some WCAG AA failures |
|
||||
| F | Failing - Major accessibility issues |
|
||||
59
plugins/viz-platform/skills/chart-types.md
Normal file
59
plugins/viz-platform/skills/chart-types.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Chart Types Reference
|
||||
|
||||
## Available Chart Types
|
||||
|
||||
| Type | Best For |
|
||||
|------|----------|
|
||||
| `line` | Time series, trends |
|
||||
| `bar` | Comparisons, categories |
|
||||
| `scatter` | Correlations, distributions |
|
||||
| `pie` | Part-to-whole relationships |
|
||||
| `area` | Cumulative trends |
|
||||
| `histogram` | Frequency distributions |
|
||||
| `box` | Statistical distributions |
|
||||
| `heatmap` | Matrix correlations |
|
||||
| `sunburst` | Hierarchical data |
|
||||
| `treemap` | Hierarchical proportions |
|
||||
|
||||
## Theme Integration
|
||||
|
||||
Charts automatically inherit from active theme:
|
||||
- Primary color for main data
|
||||
- Color palette for multi-series
|
||||
- Font family and sizes
|
||||
- Background colors
|
||||
|
||||
Override with explicit theme:
|
||||
```python
|
||||
chart_create(chart_type="bar", ..., theme="my-dark-theme")
|
||||
```
|
||||
|
||||
## Export Formats
|
||||
|
||||
| Format | Best For | File Size |
|
||||
|--------|----------|-----------|
|
||||
| `png` | Web, presentations, general use | Medium |
|
||||
| `svg` | Scalable graphics, editing | Small |
|
||||
| `pdf` | Print, documents, archival | Large |
|
||||
|
||||
## Resolution Options
|
||||
|
||||
### Scale Factor
|
||||
- `1` - Standard resolution (72 DPI)
|
||||
- `2` - Retina/HiDPI (144 DPI)
|
||||
- `3` - Print quality (216 DPI)
|
||||
- `4` - High-quality print (288 DPI)
|
||||
|
||||
## Export Requirements
|
||||
|
||||
Requires `kaleido` package:
|
||||
```bash
|
||||
pip install kaleido
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
Charts return Plotly figure JSON that can be:
|
||||
- Rendered in a Dash app
|
||||
- Saved as HTML/PNG/SVG/PDF
|
||||
- Embedded in a layout component
|
||||
97
plugins/viz-platform/skills/dmc-components.md
Normal file
97
plugins/viz-platform/skills/dmc-components.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Dash Mantine Components Reference
|
||||
|
||||
## Component Categories
|
||||
|
||||
| Category | Components |
|
||||
|----------|------------|
|
||||
| `inputs` | Button, TextInput, Select, Checkbox, Radio, Switch, Slider, etc. |
|
||||
| `navigation` | NavLink, Tabs, Breadcrumbs, Pagination, Stepper |
|
||||
| `feedback` | Alert, Notification, Progress, Loader, Skeleton |
|
||||
| `overlays` | Modal, Drawer, Tooltip, Popover, Menu |
|
||||
| `typography` | Text, Title, Code, Blockquote, List |
|
||||
| `layout` | Container, Grid, Stack, Group, Space, Divider |
|
||||
| `data` | Table, Badge, Card, Paper, Timeline |
|
||||
|
||||
## Common Props
|
||||
|
||||
Most components share these props:
|
||||
|
||||
| Prop | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `size` | xs, sm, md, lg, xl | Component size |
|
||||
| `radius` | xs, sm, md, lg, xl | Border radius |
|
||||
| `color` | string | Theme color name |
|
||||
| `variant` | string | Style variant |
|
||||
| `disabled` | boolean | Disable interaction |
|
||||
|
||||
## Component Validation
|
||||
|
||||
Why validation matters:
|
||||
- Prevents hallucinated prop names
|
||||
- Validates enum values
|
||||
- Catches typos before runtime
|
||||
- Documents available options
|
||||
|
||||
### Validation Response
|
||||
|
||||
```json
|
||||
{
|
||||
"valid": true,
|
||||
"errors": [],
|
||||
"warnings": []
|
||||
}
|
||||
```
|
||||
|
||||
With errors:
|
||||
```json
|
||||
{
|
||||
"valid": false,
|
||||
"errors": [
|
||||
"Invalid prop 'colour' for Button. Did you mean 'color'?",
|
||||
"Prop 'size' expects one of ['xs', 'sm', 'md', 'lg', 'xl'], got 'huge'"
|
||||
],
|
||||
"warnings": [
|
||||
"Prop 'fullwidth' should be 'fullWidth' (camelCase)"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Grid System
|
||||
|
||||
DMC Grid with responsive spans:
|
||||
|
||||
```python
|
||||
dmc.Grid(
|
||||
children=[
|
||||
dmc.GridCol(
|
||||
children=[chart],
|
||||
span={"base": 12, "sm": 6, "lg": 4}
|
||||
)
|
||||
],
|
||||
gutter="md"
|
||||
)
|
||||
```
|
||||
|
||||
## Button Example
|
||||
|
||||
```json
|
||||
{
|
||||
"component": "Button",
|
||||
"props": {
|
||||
"variant": {
|
||||
"type": "string",
|
||||
"enum": ["filled", "outline", "light", "subtle", "default", "gradient"],
|
||||
"default": "filled"
|
||||
},
|
||||
"color": {
|
||||
"type": "string",
|
||||
"default": "blue"
|
||||
},
|
||||
"size": {
|
||||
"type": "string",
|
||||
"enum": ["xs", "sm", "md", "lg", "xl"],
|
||||
"default": "sm"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
70
plugins/viz-platform/skills/layout-templates.md
Normal file
70
plugins/viz-platform/skills/layout-templates.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Layout Templates
|
||||
|
||||
## Available Templates
|
||||
|
||||
### Basic
|
||||
Single-column layout with header and content area.
|
||||
```
|
||||
+-----------------------------+
|
||||
| Header |
|
||||
+-----------------------------+
|
||||
| |
|
||||
| Content |
|
||||
| |
|
||||
+-----------------------------+
|
||||
```
|
||||
|
||||
### Sidebar
|
||||
Layout with collapsible sidebar navigation.
|
||||
```
|
||||
+--------+--------------------+
|
||||
| | Header |
|
||||
| Nav +--------------------+
|
||||
| | |
|
||||
| | Content |
|
||||
| | |
|
||||
+--------+--------------------+
|
||||
```
|
||||
|
||||
### Tabs
|
||||
Tabbed layout for multi-page dashboards.
|
||||
```
|
||||
+-----------------------------+
|
||||
| Header |
|
||||
+------+------+------+--------+
|
||||
| Tab1 | Tab2 | Tab3 | |
|
||||
+------+------+------+--------+
|
||||
| |
|
||||
| Tab Content |
|
||||
| |
|
||||
+-----------------------------+
|
||||
```
|
||||
|
||||
### Split
|
||||
Split-pane layout for comparisons.
|
||||
```
|
||||
+-----------------------------+
|
||||
| Header |
|
||||
+--------------+--------------+
|
||||
| | |
|
||||
| Left | Right |
|
||||
| Pane | Pane |
|
||||
| | |
|
||||
+--------------+--------------+
|
||||
```
|
||||
|
||||
## Filter Types
|
||||
|
||||
Available filter components:
|
||||
- `dropdown` - Single/multi-select dropdown
|
||||
- `date_range` - Date range picker
|
||||
- `slider` - Numeric range slider
|
||||
- `checkbox` - Checkbox group
|
||||
- `search` - Text search input
|
||||
|
||||
## Output
|
||||
|
||||
Layout structures can be:
|
||||
- Used with page tools to create full app
|
||||
- Rendered as a Dash layout
|
||||
- Combined with chart components
|
||||
159
plugins/viz-platform/skills/mcp-tools-reference.md
Normal file
159
plugins/viz-platform/skills/mcp-tools-reference.md
Normal file
@@ -0,0 +1,159 @@
|
||||
# Viz-Platform MCP Tools Reference
|
||||
|
||||
## Tool Categories
|
||||
|
||||
| Category | Tools |
|
||||
|----------|-------|
|
||||
| DMC Validation | `list_components`, `get_component_props`, `validate_component` |
|
||||
| Charts | `chart_create`, `chart_configure_interaction`, `chart_export` |
|
||||
| Layouts | `layout_create`, `layout_add_filter`, `layout_set_grid`, `layout_set_breakpoints` |
|
||||
| Themes | `theme_create`, `theme_extend`, `theme_validate`, `theme_export_css`, `theme_list`, `theme_activate` |
|
||||
| Pages | `page_create`, `page_add_navbar`, `page_set_auth` |
|
||||
| Accessibility | `accessibility_validate_colors`, `accessibility_validate_theme`, `accessibility_suggest_alternative` |
|
||||
|
||||
## DMC Validation Tools
|
||||
|
||||
### list_components
|
||||
```python
|
||||
list_components(category=None) # All components
|
||||
list_components(category="inputs") # Filter by category
|
||||
```
|
||||
|
||||
### get_component_props
|
||||
```python
|
||||
get_component_props(component="Button")
|
||||
```
|
||||
|
||||
### validate_component
|
||||
```python
|
||||
validate_component(
|
||||
component="Button",
|
||||
props={"variant": "filled", "color": "blue"}
|
||||
)
|
||||
```
|
||||
|
||||
## Chart Tools
|
||||
|
||||
### chart_create
|
||||
```python
|
||||
chart_create(
|
||||
chart_type="line",
|
||||
data_ref="df_sales",
|
||||
x="date",
|
||||
y="revenue",
|
||||
color=None,
|
||||
title="Sales Over Time",
|
||||
theme=None
|
||||
)
|
||||
```
|
||||
|
||||
### chart_export
|
||||
```python
|
||||
chart_export(
|
||||
figure=figure_json,
|
||||
format="png", # png, svg, pdf
|
||||
width=1200,
|
||||
height=800,
|
||||
scale=2,
|
||||
output_path=None
|
||||
)
|
||||
```
|
||||
|
||||
## Layout Tools
|
||||
|
||||
### layout_create
|
||||
```python
|
||||
layout_create(
|
||||
name="my-dashboard",
|
||||
template="sidebar" # basic, sidebar, tabs, split
|
||||
)
|
||||
```
|
||||
|
||||
### layout_add_filter
|
||||
```python
|
||||
layout_add_filter(
|
||||
layout_ref="my-dashboard",
|
||||
filter_type="dropdown", # dropdown, date_range, slider, checkbox, search
|
||||
options={}
|
||||
)
|
||||
```
|
||||
|
||||
### layout_set_grid
|
||||
```python
|
||||
layout_set_grid(
|
||||
layout_ref="my-dashboard",
|
||||
cols=12,
|
||||
spacing="md"
|
||||
)
|
||||
```
|
||||
|
||||
### layout_set_breakpoints
|
||||
```python
|
||||
layout_set_breakpoints(
|
||||
layout_ref="my-dashboard",
|
||||
breakpoints={
|
||||
"xs": {"cols": 1, "spacing": "xs"},
|
||||
"sm": {"cols": 2, "spacing": "sm"},
|
||||
"md": {"cols": 6, "spacing": "md"},
|
||||
"lg": {"cols": 12, "spacing": "md"},
|
||||
"xl": {"cols": 12, "spacing": "lg"}
|
||||
},
|
||||
mobile_first=True
|
||||
)
|
||||
```
|
||||
|
||||
## Theme Tools
|
||||
|
||||
### theme_create
|
||||
```python
|
||||
theme_create(
|
||||
name="corporate",
|
||||
primary_color="indigo",
|
||||
color_scheme="light",
|
||||
font_family="Inter, sans-serif",
|
||||
heading_font_family=None,
|
||||
border_radius="md",
|
||||
spacing_scale=1.0,
|
||||
colors=None
|
||||
)
|
||||
```
|
||||
|
||||
### theme_extend
|
||||
```python
|
||||
theme_extend(
|
||||
base_theme="dark",
|
||||
name="dark-corporate",
|
||||
overrides={"primary_color": "indigo"}
|
||||
)
|
||||
```
|
||||
|
||||
### theme_validate
|
||||
```python
|
||||
theme_validate(theme_name="corporate")
|
||||
```
|
||||
|
||||
### theme_export_css
|
||||
```python
|
||||
theme_export_css(theme_name="corporate")
|
||||
```
|
||||
|
||||
### theme_activate
|
||||
```python
|
||||
theme_activate(theme_name="dark")
|
||||
```
|
||||
|
||||
## Accessibility Tools
|
||||
|
||||
### accessibility_validate_colors
|
||||
```python
|
||||
accessibility_validate_colors(
|
||||
colors=["#228be6", "#40c057", "#fa5252"],
|
||||
check_types=["deuteranopia", "protanopia", "tritanopia"],
|
||||
min_contrast_ratio=4.5
|
||||
)
|
||||
```
|
||||
|
||||
### accessibility_validate_theme
|
||||
```python
|
||||
accessibility_validate_theme(theme_name="corporate")
|
||||
```
|
||||
104
plugins/viz-platform/skills/responsive-design.md
Normal file
104
plugins/viz-platform/skills/responsive-design.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Responsive Design
|
||||
|
||||
## Breakpoint Sizes
|
||||
|
||||
| Name | Min Width | Common Devices |
|
||||
|------|-----------|----------------|
|
||||
| `xs` | 0px | Small phones (portrait) |
|
||||
| `sm` | 576px | Large phones, small tablets |
|
||||
| `md` | 768px | Tablets (portrait) |
|
||||
| `lg` | 992px | Tablets (landscape), laptops |
|
||||
| `xl` | 1200px | Desktops, large screens |
|
||||
|
||||
## Mobile-First Approach
|
||||
|
||||
When `mobile_first=True` (default), styles cascade up:
|
||||
- Define base styles for `xs` (mobile)
|
||||
- Override only what changes at larger breakpoints
|
||||
- Smaller CSS footprint, better performance
|
||||
|
||||
```python
|
||||
{
|
||||
"xs": {"cols": 1}, # Stack everything on mobile
|
||||
"md": {"cols": 6}, # Two-column on tablet
|
||||
"lg": {"cols": 12} # Full grid on desktop
|
||||
}
|
||||
```
|
||||
|
||||
When `mobile_first=False`, styles cascade down (desktop-first).
|
||||
|
||||
## Grid Configuration
|
||||
|
||||
Each breakpoint can configure:
|
||||
|
||||
| Property | Description | Values |
|
||||
|----------|-------------|--------|
|
||||
| `cols` | Grid column count | 1-24 |
|
||||
| `spacing` | Gap between items | xs, sm, md, lg, xl |
|
||||
| `gutter` | Outer padding | xs, sm, md, lg, xl |
|
||||
| `grow` | Items grow to fill | true, false |
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Dashboard (Charts & Filters)
|
||||
```python
|
||||
{
|
||||
"xs": {"cols": 1, "spacing": "xs"},
|
||||
"sm": {"cols": 2, "spacing": "sm"},
|
||||
"md": {"cols": 3, "spacing": "md"},
|
||||
"lg": {"cols": 4, "spacing": "md"},
|
||||
"xl": {"cols": 6, "spacing": "lg"}
|
||||
}
|
||||
```
|
||||
|
||||
### Data Table
|
||||
```python
|
||||
{
|
||||
"xs": {"cols": 1, "scroll": true},
|
||||
"md": {"cols": 1, "scroll": false},
|
||||
"lg": {"cols": 1}
|
||||
}
|
||||
```
|
||||
|
||||
### Form Layout
|
||||
```python
|
||||
{
|
||||
"xs": {"cols": 1},
|
||||
"md": {"cols": 2},
|
||||
"lg": {"cols": 3}
|
||||
}
|
||||
```
|
||||
|
||||
### Sidebar Layout
|
||||
```python
|
||||
{
|
||||
"xs": {"sidebar": "hidden"},
|
||||
"md": {"sidebar": "collapsed"},
|
||||
"lg": {"sidebar": "expanded"}
|
||||
}
|
||||
```
|
||||
|
||||
## Component Span
|
||||
|
||||
Control how many columns a component spans:
|
||||
|
||||
```python
|
||||
{
|
||||
"component": "sales-chart",
|
||||
"span": {
|
||||
"xs": 1, # Full width (1/1)
|
||||
"md": 3, # Half width (3/6)
|
||||
"lg": 6 # Half width (6/12)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## CSS Media Queries
|
||||
|
||||
Generated for each breakpoint:
|
||||
```css
|
||||
@media (min-width: 576px) { ... }
|
||||
@media (min-width: 768px) { ... }
|
||||
@media (min-width: 992px) { ... }
|
||||
@media (min-width: 1200px) { ... }
|
||||
```
|
||||
104
plugins/viz-platform/skills/theming-system.md
Normal file
104
plugins/viz-platform/skills/theming-system.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Theming System
|
||||
|
||||
## Design Tokens
|
||||
|
||||
Themes define design tokens for consistent styling across components.
|
||||
|
||||
### Theme Properties
|
||||
|
||||
| Category | Properties |
|
||||
|----------|------------|
|
||||
| Colors | `primary_color`, `color_scheme`, `colors` |
|
||||
| Typography | `font_family`, `heading_font_family` |
|
||||
| Spacing | `border_radius`, `spacing_scale` |
|
||||
|
||||
### Color Scheme
|
||||
- `light` - Light background, dark text
|
||||
- `dark` - Dark background, light text
|
||||
|
||||
### Border Radius Scale
|
||||
| Size | Value |
|
||||
|------|-------|
|
||||
| xs | 0.125rem |
|
||||
| sm | 0.25rem |
|
||||
| md | 0.5rem |
|
||||
| lg | 1rem |
|
||||
| xl | 2rem |
|
||||
|
||||
## Mantine Color Palette
|
||||
|
||||
Available primary colors:
|
||||
- blue, cyan, teal, green, lime
|
||||
- yellow, orange, red, pink, grape
|
||||
- violet, indigo, gray, dark
|
||||
|
||||
Each color has 10 shades (0-9), where 5 is the primary shade.
|
||||
|
||||
## Custom Color Definition
|
||||
|
||||
```python
|
||||
colors={
|
||||
"custom": [
|
||||
"#e6f7ff", # 0 - lightest
|
||||
"#bae7ff", # 1
|
||||
"#91d5ff", # 2
|
||||
"#69c0ff", # 3
|
||||
"#40a9ff", # 4
|
||||
"#1890ff", # 5 - primary
|
||||
"#096dd9", # 6
|
||||
"#0050b3", # 7
|
||||
"#003a8c", # 8
|
||||
"#002766" # 9 - darkest
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## CSS Custom Properties
|
||||
|
||||
Exported themes use Mantine CSS variable naming:
|
||||
|
||||
```css
|
||||
:root {
|
||||
/* Colors */
|
||||
--mantine-color-scheme: light;
|
||||
--mantine-primary-color: indigo;
|
||||
--mantine-color-primary-0: #edf2ff;
|
||||
--mantine-color-primary-5: #5c7cfa;
|
||||
--mantine-color-primary-9: #364fc7;
|
||||
|
||||
/* Typography */
|
||||
--mantine-font-family: Inter, sans-serif;
|
||||
--mantine-font-size-xs: 0.75rem;
|
||||
--mantine-font-size-md: 1rem;
|
||||
|
||||
/* Spacing */
|
||||
--mantine-spacing-xs: 0.625rem;
|
||||
--mantine-spacing-md: 1rem;
|
||||
|
||||
/* Border Radius */
|
||||
--mantine-radius-sm: 0.25rem;
|
||||
--mantine-radius-md: 0.5rem;
|
||||
|
||||
/* Shadows */
|
||||
--mantine-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
--mantine-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
```
|
||||
|
||||
## Theme Inheritance
|
||||
|
||||
Create themes based on existing ones:
|
||||
```python
|
||||
theme_extend(
|
||||
base_theme="dark",
|
||||
name="dark-corporate",
|
||||
overrides={"primary_color": "indigo"}
|
||||
)
|
||||
```
|
||||
|
||||
## Built-in Themes
|
||||
|
||||
| Theme | Description |
|
||||
|-------|-------------|
|
||||
| `light` | Mantine default light mode |
|
||||
| `dark` | Mantine default dark mode |
|
||||
Reference in New Issue
Block a user