databuild/plans/webapp_v1/chunk-6-partition-pages.md

224 lines
No EOL
6.2 KiB
Markdown

# Chunk 6: Partition Pages
**Parent:** [Build Graph Dashboard](../build-graph-dashboard.md)
**Previous:** [Chunk 5: Build Status](./chunk-5-build-status.md)
**Next:** [Chunk 7: Jobs Pages](./chunk-7-jobs-pages.md)
## Overview
Implement partition listing and individual partition status pages with build history, "Build Now" functionality, and related partition discovery.
## Scope
### In Scope
- Partition listing page with search functionality
- Individual partition status pages
- Build history for each partition
- "Build Now" button with force rebuild option
- Related partitions (upstream/downstream dependencies)
- Partition reference URL handling with base64 encoding
### Out of Scope
- Complex dependency graph visualization
- Partition metadata beyond build history
- Advanced filtering beyond basic search
- Batch operations on multiple partitions
## Technical Approach
### Data Sources
From Build Graph Service API:
- `/api/v1/partitions/:ref/status` - Partition status and metadata
- `/api/v1/partitions/:ref/events` - Build events for partition
- `/api/v1/builds` - Submit new build requests
- Recent partitions from build event log
### URL Encoding
```typescript
// Handle partition references in URLs
function encodePartitionRef(ref: string): string {
return btoa(ref).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}
function decodePartitionRef(encoded: string): string {
// Add padding if needed
const padded = encoded.replace(/-/g, '+').replace(/_/g, '/');
return atob(padded);
}
```
### Component Structure
```typescript
const PartitionsList = {
oninit: () => {
this.partitions = [];
this.searchTerm = '';
this.loadPartitions();
},
view: () => [
m('.partitions-header', [
m('h1', 'Partitions'),
m('input', {
placeholder: 'Search partitions...',
oninput: (e) => this.searchTerm = e.target.value,
})
]),
m('.partitions-table', [
m('table.table', [
m('thead', [
m('tr', [
m('th', 'Partition Reference'),
m('th', 'Status'),
m('th', 'Last Updated'),
m('th', 'Actions'),
])
]),
m('tbody', this.filteredPartitions().map(partition =>
m('tr', [
m('td', m('a', {
href: `/partitions/${encodePartitionRef(partition.ref)}`
}, partition.ref)),
m('td', m('.badge', partition.status)),
m('td', formatTime(partition.last_updated)),
m('td', [
m('button.btn.btn-sm', {
onclick: () => this.buildPartition(partition.ref)
}, 'Build')
])
])
))
])
])
]
};
const PartitionStatus = {
oninit: (vnode) => {
this.partitionRef = decodePartitionRef(vnode.attrs.base64_ref);
this.partition = null;
this.buildHistory = [];
this.relatedPartitions = [];
this.loadPartition();
},
view: () => [
m('.partition-header', [
m('h1', this.partitionRef),
m('.partition-meta', [
m('.badge', this.partition?.status),
m('.timestamp', formatTime(this.partition?.last_updated)),
]),
m('.partition-actions', [
m('button.btn.btn-primary', {
onclick: () => this.buildPartition(false)
}, 'Build Now'),
m('button.btn.btn-secondary', {
onclick: () => this.buildPartition(true)
}, 'Force Rebuild'),
])
]),
m('.partition-content', [
m('.build-history', [
m('h2', 'Build History'),
m('table.table', [
m('thead', [
m('tr', [
m('th', 'Build Request'),
m('th', 'Status'),
m('th', 'Started'),
m('th', 'Completed'),
])
]),
m('tbody', this.buildHistory.map(build =>
m('tr', [
m('td', m('a', { href: `/builds/${build.id}` }, build.id)),
m('td', m('.badge', build.status)),
m('td', formatTime(build.started_at)),
m('td', formatTime(build.completed_at)),
])
))
])
]),
m('.related-partitions', [
m('h2', 'Related Partitions'),
m('.partition-deps', [
m('h3', 'Dependencies'),
m('ul', this.relatedPartitions.dependencies?.map(dep =>
m('li', m('a', {
href: `/partitions/${encodePartitionRef(dep)}`
}, dep))
))
]),
m('.partition-dependents', [
m('h3', 'Dependents'),
m('ul', this.relatedPartitions.dependents?.map(dep =>
m('li', m('a', {
href: `/partitions/${encodePartitionRef(dep)}`
}, dep))
))
])
])
])
]
};
```
### Build Now Functionality
- Submit build request for specific partition
- Handle force rebuild option
- Redirect to build status page
- Show loading states during submission
## Implementation Strategy
1. **Create Data Layer**
- API integration for partition data
- Search and filtering logic
- Build request submission
2. **Build List Page**
- Partition table with search
- Status indicators
- Quick build actions
3. **Individual Partition Pages**
- Partition status display
- Build history table
- Related partitions discovery
4. **Build Actions**
- "Build Now" functionality
- Force rebuild option
- Error handling and feedback
## Deliverables
- [ ] Partition listing page with search
- [ ] Individual partition status pages
- [ ] Build history display
- [ ] "Build Now" and force rebuild functionality
- [ ] Related partitions discovery
- [ ] URL encoding/decoding for partition references
## Success Criteria
- Partition list loads and search works correctly
- Individual partition pages display complete information
- Build history shows all relevant builds
- "Build Now" successfully submits builds
- Related partitions are discoverable
- URL encoding handles all partition reference formats
## Testing
- Test partition list search with various terms
- Verify individual partition pages load correctly
- Test build history display and links
- Submit builds and verify they start correctly
- Test force rebuild functionality
- Validate URL encoding with complex partition references
- Check related partitions discovery