Skip to content

Commit

Permalink
add class path breadcrumbs to class editor
Browse files Browse the repository at this point in the history
  • Loading branch information
baumths committed Sep 17, 2024
1 parent 065918a commit 0ef4eed
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 65 deletions.
57 changes: 57 additions & 0 deletions lib/features/class_editor/breadcrumbs.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import '../settings/settings_controller.dart';
import 'class_editor.dart';
import 'earq_brasil_metadata.dart';

class ClassEditorBreadcrumbs extends StatelessWidget {
const ClassEditorBreadcrumbs({super.key});

static const Widget separator = Icon(Icons.chevron_right, size: 20);

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final editor = context.read<ClassEditor>();

final subordination = editor.valueOf(EarqBrasilMetadata.subordinacao);
if (subordination == null || subordination.isEmpty) {
return const SizedBox.shrink();
}

final institutionCode = context.select<SettingsController, String>(
(settings) => settings.institutionCode,
);

final breadcrumbs = subordination.split('-');

final code = context.select<ClassEditor, String?>(
(editor) => editor.valueOf(EarqBrasilMetadata.codigo),
);

return DefaultTextStyle(
style: theme.textTheme.titleSmall!,
child: Wrap(
spacing: 8,
runSpacing: 8,
children: [
Text(institutionCode),
separator,
for (int index = 0; index < breadcrumbs.length * 2 - 1; index++)
index.isEven ? Text(breadcrumbs[index ~/ 2]) : separator,
if (code != null && code.isNotEmpty) ...[
separator,
Text(
code,
style: TextStyle(
color: theme.colorScheme.primary,
fontWeight: FontWeight.bold,
),
),
],
],
),
);
}
}
5 changes: 3 additions & 2 deletions lib/features/class_editor/class_editor.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import 'package:flutter/foundation.dart' show visibleForTesting;
import 'package:flutter/foundation.dart' show ChangeNotifier, visibleForTesting;

import '../../entities/classe.dart';
import '../../repositories/classes_repository.dart';
import 'earq_brasil_metadata.dart';

class ClassEditor {
class ClassEditor with ChangeNotifier {
ClassEditor({
required ClassesRepository repository,
int? parentId,
Expand Down Expand Up @@ -47,6 +47,7 @@ class ClassEditor {

void updateValueOf(EarqBrasilMetadata entry, String value) {
metadata[entry.key] = value;
notifyListeners();
}

Classe save() {
Expand Down
93 changes: 49 additions & 44 deletions lib/features/class_editor/class_editor_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,10 @@ import '../../app/navigator.dart' as navigator;
import '../../localization.dart';
import '../../repositories/classes_repository.dart';
import '../../shared/snackbars.dart';
import 'breadcrumbs.dart';
import 'class_editor.dart';
import 'earq_brasil_form.dart';

void _onSavePressed(BuildContext context) {
try {
context.read<ClassEditor>().save();
} on Exception {
showErrorSnackBar(
context,
AppLocalizations.of(context).unableToSaveClassSnackbarText,
);
} finally {
navigator.closeClassEditor();
}
}

class ClassEditorScreen extends StatefulWidget {
const ClassEditorScreen({super.key, this.classId, this.parentId});

Expand All @@ -44,56 +32,54 @@ class _ClassEditorScreenState extends State<ClassEditorScreen> {
)..init(editingClassId: widget.classId);
}

@override
Widget build(BuildContext context) {
return Provider<ClassEditor>.value(
value: editor,
child: const Material(
child: ClassEditorShortcuts(
child: Column(
children: [
Expanded(child: EarqBrasilForm()),
Divider(height: 1, thickness: 1),
ClassEditorActionButtons(),
],
),
),
),
);
}
}

class ClassEditorActionButtons extends StatelessWidget {
const ClassEditorActionButtons({super.key});

@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context);

return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
return ChangeNotifierProvider<ClassEditor>.value(
value: editor,
child: Scaffold(
body: ClassEditorShortcuts(
onSave: onSavePressed,
child: const ClassEditorBody(),
),
persistentFooterButtons: [
TextButton(
onPressed: navigator.closeClassEditor,
child: Text(l10n.cancelButtonText),
),
const SizedBox(width: 8),
FilledButton(
onPressed: () => _onSavePressed(context),
onPressed: onSavePressed,
child: Text(l10n.saveButtonText),
),
],
),
);
}

void onSavePressed() {
try {
editor.save();
} on Exception {
showErrorSnackBar(
context,
AppLocalizations.of(context).unableToSaveClassSnackbarText,
);
} finally {
navigator.closeClassEditor();
}
}
}

class ClassEditorShortcuts extends StatelessWidget {
const ClassEditorShortcuts({super.key, required this.child});
const ClassEditorShortcuts({
super.key,
required this.child,
required this.onSave,
});

final Widget child;
final VoidCallback onSave;

@override
Widget build(BuildContext context) {
Expand All @@ -104,9 +90,28 @@ class ClassEditorShortcuts extends StatelessWidget {
LogicalKeyboardKey.keyS,
control: true,
includeRepeats: false,
): VoidCallbackIntent(() => _onSavePressed(context)),
): VoidCallbackIntent(onSave),
},
child: child,
);
}
}

class ClassEditorBody extends StatelessWidget {
const ClassEditorBody({super.key});

@override
Widget build(BuildContext context) {
return const SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClassEditorBreadcrumbs(),
SizedBox(height: 16),
EarqBrasilForm(),
],
),
);
}
}
36 changes: 17 additions & 19 deletions lib/features/class_editor/earq_brasil_form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,23 @@ class EarqBrasilForm extends StatelessWidget {
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: constraints.maxWidth >= 700
? const Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(child: DescriptionSection()),
_formFieldsGap,
Expanded(child: TemporalitySection()),
],
)
: const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
DescriptionSection(),
_formFieldsGap,
TemporalitySection(),
],
),
if (constraints.maxWidth >= 700) {
return const Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(child: DescriptionSection()),
_formFieldsGap,
Expanded(child: TemporalitySection()),
],
);
}
return const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
DescriptionSection(),
_formFieldsGap,
TemporalitySection(),
],
);
},
);
Expand Down

0 comments on commit 0ef4eed

Please sign in to comment.