forked from eva/focus-flow
chore: remove dead BacklogPane widget superseded by BacklogBoardScreen
Closes: #9
This commit is contained in:
parent
383130ebdb
commit
92e5358c02
1 changed files with 0 additions and 182 deletions
|
|
@ -1,182 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2026 FocusFlow contributors
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
/// Renders the Backlog Pane widget for the FocusFlow Flutter UI.
|
|
||||||
library;
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:scheduler_core/scheduler_core.dart';
|
|
||||||
|
|
||||||
import '../controllers/scheduler_command_controller.dart';
|
|
||||||
import '../controllers/scheduler_read_controller.dart';
|
|
||||||
import 'read_state_view.dart';
|
|
||||||
import 'schedule_components.dart';
|
|
||||||
|
|
||||||
/// Read-driven pane that renders backlog content and command controls.
|
|
||||||
class BacklogPane extends StatelessWidget {
|
|
||||||
/// Creates a backlog pane from a read [controller].
|
|
||||||
const BacklogPane({
|
|
||||||
required this.controller,
|
|
||||||
this.commandController,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Controller that loads backlog data.
|
|
||||||
final UiReadController<BacklogQueryResult> controller;
|
|
||||||
|
|
||||||
/// Optional command controller for mutating backlog items.
|
|
||||||
final SchedulerCommandController? commandController;
|
|
||||||
|
|
||||||
/// Builds the widget subtree for this component.
|
|
||||||
/// The method translates the current widget configuration and state into Flutter UI without mutating scheduler domain data.
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return ReadStateView<BacklogQueryResult>(
|
|
||||||
controller: controller,
|
|
||||||
title: 'Backlog',
|
|
||||||
emptyTitle: 'Backlog is clear',
|
|
||||||
emptyMessage: 'Captured tasks will appear here when they need planning.',
|
|
||||||
dataBuilder: (context, result) =>
|
|
||||||
BacklogContent(result: result, commandController: commandController),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Populated backlog view for a loaded backlog query result.
|
|
||||||
class BacklogContent extends StatelessWidget {
|
|
||||||
/// Creates backlog content for [result].
|
|
||||||
const BacklogContent({
|
|
||||||
required this.result,
|
|
||||||
this.commandController,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Loaded backlog result to display.
|
|
||||||
final BacklogQueryResult result;
|
|
||||||
|
|
||||||
/// Optional command controller for capture and scheduling actions.
|
|
||||||
final SchedulerCommandController? commandController;
|
|
||||||
|
|
||||||
/// Builds the widget subtree for this component.
|
|
||||||
/// The method translates the current widget configuration and state into Flutter UI without mutating scheduler domain data.
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return ListView(
|
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
children: [
|
|
||||||
Text('Backlog', style: Theme.of(context).textTheme.headlineMedium),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
if (commandController != null) ...[
|
|
||||||
QuickCaptureForm(commandController: commandController!),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
CommandStatusBanner(controller: commandController!),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
],
|
|
||||||
for (final item in result.items)
|
|
||||||
BacklogRow(
|
|
||||||
item: item,
|
|
||||||
onSchedule: commandController == null
|
|
||||||
? null
|
|
||||||
: (durationMinutes) {
|
|
||||||
return commandController!.scheduleBacklogItem(
|
|
||||||
taskId: item.task.id,
|
|
||||||
durationMinutes: durationMinutes,
|
|
||||||
expectedUpdatedAt: item.task.updatedAt,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Small form for quickly capturing a task into the backlog.
|
|
||||||
class QuickCaptureForm extends StatefulWidget {
|
|
||||||
/// Creates a quick capture form.
|
|
||||||
const QuickCaptureForm({required this.commandController, super.key});
|
|
||||||
|
|
||||||
/// Command controller used to submit captured task titles.
|
|
||||||
final SchedulerCommandController commandController;
|
|
||||||
|
|
||||||
/// Creates the mutable state object used by this stateful widget.
|
|
||||||
/// Flutter calls this once for each mounted widget instance before lifecycle callbacks and builds begin.
|
|
||||||
@override
|
|
||||||
State<QuickCaptureForm> createState() => _QuickCaptureFormState();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Private implementation type for `_QuickCaptureFormState` in this library.
|
|
||||||
/// It keeps supporting state and behavior scoped to the owning file so the public API stays focused on the scheduler concepts that callers use directly.
|
|
||||||
class _QuickCaptureFormState extends State<QuickCaptureForm> {
|
|
||||||
/// Stores the `titleController` value for this object.
|
|
||||||
/// This field is part of the explicit state that downstream scheduling, persistence, or UI code reads when composing behavior.
|
|
||||||
final titleController = TextEditingController();
|
|
||||||
|
|
||||||
/// Releases resources owned by this object before it leaves the tree.
|
|
||||||
/// Controllers, listeners, and other disposable collaborators should be cleaned up here to avoid stale callbacks.
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
titleController.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds the widget subtree for this component.
|
|
||||||
/// The method translates the current widget configuration and state into Flutter UI without mutating scheduler domain data.
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: TextField(
|
|
||||||
key: const ValueKey('quick-capture-title'),
|
|
||||||
controller: titleController,
|
|
||||||
decoration: const InputDecoration(labelText: 'Quick capture'),
|
|
||||||
textInputAction: TextInputAction.done,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
FilledButton.icon(
|
|
||||||
onPressed: () async {
|
|
||||||
final title = titleController.text.trim();
|
|
||||||
if (title.isEmpty) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await widget.commandController.quickCaptureToBacklog(title);
|
|
||||||
titleController.clear();
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.add),
|
|
||||||
label: const Text('Capture'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Displays the latest command state for backlog interactions.
|
|
||||||
class CommandStatusBanner extends StatelessWidget {
|
|
||||||
/// Creates a command status banner.
|
|
||||||
const CommandStatusBanner({required this.controller, super.key});
|
|
||||||
|
|
||||||
/// Command controller whose state should be rendered.
|
|
||||||
final SchedulerCommandController controller;
|
|
||||||
|
|
||||||
/// Builds the widget subtree for this component.
|
|
||||||
/// The method translates the current widget configuration and state into Flutter UI without mutating scheduler domain data.
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return AnimatedBuilder(
|
|
||||||
animation: controller,
|
|
||||||
builder: (context, _) {
|
|
||||||
return switch (controller.state) {
|
|
||||||
SchedulerCommandIdle() => const SizedBox.shrink(),
|
|
||||||
SchedulerCommandRunning(label: final label) => Text(label),
|
|
||||||
SchedulerCommandSuccess(message: final message) => Text(message),
|
|
||||||
SchedulerCommandFailure(failure: final failure, error: final error) =>
|
|
||||||
Text(
|
|
||||||
'Command issue: '
|
|
||||||
'${failure?.detailCode ?? failure?.code.name ?? error ?? 'unexpected'}',
|
|
||||||
),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue