Add rapid order parsing & audio recording
Add support for transcribing and parsing rapid (urgent) orders into one-time order drafts. Introduces ParseRapidOrderTextToOrderUseCase and wiring for TranscribeRapidOrderUseCase, implements parseRapidOrder and transcribeRapidOrder in the client repository, and injects these into the RapidOrderBloc and module. Adds the record package dependency and registers the record plugin for iOS/macOS targets. Updates OneTimeOrder state, bloc and views to handle rapid-order drafts and navigate to the one-time order flow after parsing. Also includes small formatting and navigator changes.
This commit is contained in:
@@ -36,6 +36,12 @@
|
||||
@import image_picker_ios;
|
||||
#endif
|
||||
|
||||
#if __has_include(<record_ios/RecordIosPlugin.h>)
|
||||
#import <record_ios/RecordIosPlugin.h>
|
||||
#else
|
||||
@import record_ios;
|
||||
#endif
|
||||
|
||||
#if __has_include(<shared_preferences_foundation/SharedPreferencesPlugin.h>)
|
||||
#import <shared_preferences_foundation/SharedPreferencesPlugin.h>
|
||||
#else
|
||||
@@ -56,6 +62,7 @@
|
||||
[FLTFirebaseAuthPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseAuthPlugin"]];
|
||||
[FLTFirebaseCorePlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseCorePlugin"]];
|
||||
[FLTImagePickerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTImagePickerPlugin"]];
|
||||
[RecordIosPlugin registerWithRegistrar:[registry registrarForPlugin:@"RecordIosPlugin"]];
|
||||
[SharedPreferencesPlugin registerWithRegistrar:[registry registrarForPlugin:@"SharedPreferencesPlugin"]];
|
||||
[URLLauncherPlugin registerWithRegistrar:[registry registrarForPlugin:@"URLLauncherPlugin"]];
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import file_selector_macos
|
||||
import firebase_app_check
|
||||
import firebase_auth
|
||||
import firebase_core
|
||||
import record_macos
|
||||
import shared_preferences_foundation
|
||||
import url_launcher_macos
|
||||
|
||||
@@ -19,6 +20,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
FLTFirebaseAppCheckPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAppCheckPlugin"))
|
||||
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
|
||||
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||
RecordMacOsPlugin.register(with: registry.registrar(forPlugin: "RecordMacOsPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
}
|
||||
|
||||
@@ -54,6 +54,12 @@
|
||||
@import permission_handler_apple;
|
||||
#endif
|
||||
|
||||
#if __has_include(<record_ios/RecordIosPlugin.h>)
|
||||
#import <record_ios/RecordIosPlugin.h>
|
||||
#else
|
||||
@import record_ios;
|
||||
#endif
|
||||
|
||||
#if __has_include(<shared_preferences_foundation/SharedPreferencesPlugin.h>)
|
||||
#import <shared_preferences_foundation/SharedPreferencesPlugin.h>
|
||||
#else
|
||||
@@ -77,6 +83,7 @@
|
||||
[FLTGoogleMapsPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTGoogleMapsPlugin"]];
|
||||
[FLTImagePickerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTImagePickerPlugin"]];
|
||||
[PermissionHandlerPlugin registerWithRegistrar:[registry registrarForPlugin:@"PermissionHandlerPlugin"]];
|
||||
[RecordIosPlugin registerWithRegistrar:[registry registrarForPlugin:@"RecordIosPlugin"]];
|
||||
[SharedPreferencesPlugin registerWithRegistrar:[registry registrarForPlugin:@"SharedPreferencesPlugin"]];
|
||||
[URLLauncherPlugin registerWithRegistrar:[registry registrarForPlugin:@"URLLauncherPlugin"]];
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import firebase_app_check
|
||||
import firebase_auth
|
||||
import firebase_core
|
||||
import geolocator_apple
|
||||
import record_macos
|
||||
import shared_preferences_foundation
|
||||
import url_launcher_macos
|
||||
|
||||
@@ -21,6 +22,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
|
||||
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
|
||||
RecordMacOsPlugin.register(with: registry.registrar(forPlugin: "RecordMacOsPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ extension StaffNavigator on IModularNavigator {
|
||||
///
|
||||
/// Manage personal information, documents, and preferences.
|
||||
void toProfile() {
|
||||
pushNamedAndRemoveUntil(StaffPaths.profile, (_) => false);
|
||||
navigate(StaffPaths.profile);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
@@ -189,7 +189,7 @@ extension StaffNavigator on IModularNavigator {
|
||||
///
|
||||
/// Record previous work experience and qualifications.
|
||||
void toExperience() {
|
||||
pushNamed(StaffPaths.experience);
|
||||
navigate(StaffPaths.experience);
|
||||
}
|
||||
|
||||
/// Pushes the attire preferences page.
|
||||
|
||||
@@ -25,4 +25,5 @@ dependencies:
|
||||
image_picker: ^1.1.2
|
||||
path_provider: ^2.1.3
|
||||
file_picker: ^8.1.7
|
||||
record: ^6.2.0
|
||||
firebase_auth: ^6.1.4
|
||||
|
||||
@@ -9,6 +9,8 @@ import 'domain/usecases/create_permanent_order_usecase.dart';
|
||||
import 'domain/usecases/create_recurring_order_usecase.dart';
|
||||
import 'domain/usecases/create_rapid_order_usecase.dart';
|
||||
import 'domain/usecases/get_order_details_for_reorder_usecase.dart';
|
||||
import 'domain/usecases/parse_rapid_order_usecase.dart';
|
||||
import 'domain/usecases/transcribe_rapid_order_usecase.dart';
|
||||
import 'presentation/blocs/index.dart';
|
||||
import 'presentation/pages/create_order_page.dart';
|
||||
import 'presentation/pages/one_time_order_page.dart';
|
||||
@@ -37,10 +39,18 @@ class ClientCreateOrderModule extends Module {
|
||||
i.addLazySingleton(CreatePermanentOrderUseCase.new);
|
||||
i.addLazySingleton(CreateRecurringOrderUseCase.new);
|
||||
i.addLazySingleton(CreateRapidOrderUseCase.new);
|
||||
i.addLazySingleton(TranscribeRapidOrderUseCase.new);
|
||||
i.addLazySingleton(ParseRapidOrderTextToOrderUseCase.new);
|
||||
i.addLazySingleton(GetOrderDetailsForReorderUseCase.new);
|
||||
|
||||
// BLoCs
|
||||
i.add<RapidOrderBloc>(RapidOrderBloc.new);
|
||||
i.add<RapidOrderBloc>(
|
||||
(Injector i) => RapidOrderBloc(
|
||||
i.get<TranscribeRapidOrderUseCase>(),
|
||||
i.get<ParseRapidOrderTextToOrderUseCase>(),
|
||||
i.get<AudioRecorderService>(),
|
||||
),
|
||||
);
|
||||
i.add<OneTimeOrderBloc>(OneTimeOrderBloc.new);
|
||||
i.add<PermanentOrderBloc>(PermanentOrderBloc.new);
|
||||
i.add<RecurringOrderBloc>(RecurringOrderBloc.new);
|
||||
|
||||
@@ -367,6 +367,51 @@ class ClientCreateOrderRepositoryImpl
|
||||
throw UnimplementedError('Rapid order IA is not connected yet.');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<domain.OneTimeOrder> parseRapidOrder(String text) async {
|
||||
final RapidOrderParseResponse response = await _rapidOrderService.parseText(
|
||||
text: text,
|
||||
);
|
||||
final RapidOrderParsedData data = response.parsed;
|
||||
|
||||
final DateTime startAt =
|
||||
DateTime.tryParse(data.startAt ?? '') ?? DateTime.now();
|
||||
final DateTime endAt =
|
||||
DateTime.tryParse(data.endAt ?? '') ??
|
||||
startAt.add(const Duration(hours: 8));
|
||||
|
||||
final String startTimeStr = DateFormat('hh:mm a').format(startAt);
|
||||
final String endTimeStr = DateFormat('hh:mm a').format(endAt);
|
||||
|
||||
return domain.OneTimeOrder(
|
||||
date: startAt,
|
||||
location: data.locationHint ?? '',
|
||||
eventName: data.notes ?? '',
|
||||
hub: data.locationHint != null
|
||||
? domain.OneTimeOrderHubDetails(
|
||||
id: '',
|
||||
name: data.locationHint!,
|
||||
address: '',
|
||||
)
|
||||
: null,
|
||||
positions: data.positions.map((RapidOrderPosition p) {
|
||||
return domain.OneTimeOrderPosition(
|
||||
role: p.role,
|
||||
count: p.count,
|
||||
startTime: startTimeStr,
|
||||
endTime: endTimeStr,
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> transcribeRapidOrder(String audioPath) async {
|
||||
final RapidOrderTranscriptionResponse response = await _rapidOrderService
|
||||
.transcribeAudio(audioFileUri: audioPath);
|
||||
return response.transcript;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> reorder(String previousOrderId, DateTime newDate) async {
|
||||
// TODO: Implement reorder functionality to fetch the previous order and create a new one with the updated date.
|
||||
|
||||
@@ -24,6 +24,16 @@ abstract interface class ClientCreateOrderRepositoryInterface {
|
||||
/// [description] is the text message (or transcribed voice) describing the need.
|
||||
Future<void> createRapidOrder(String description);
|
||||
|
||||
/// Transcribes the audio file for a rapid order.
|
||||
///
|
||||
/// [audioPath] is the local path to the recorded audio file.
|
||||
Future<String> transcribeRapidOrder(String audioPath);
|
||||
|
||||
/// Parses the text description for a rapid order into a structured draft.
|
||||
///
|
||||
/// [text] is the text message describing the need.
|
||||
Future<OneTimeOrder> parseRapidOrder(String text);
|
||||
|
||||
/// Reorders an existing staffing order with a new date.
|
||||
///
|
||||
/// [previousOrderId] is the ID of the order to reorder.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import '../repositories/client_create_order_repository_interface.dart';
|
||||
|
||||
/// Use case for parsing rapid order text into a structured OneTimeOrder.
|
||||
class ParseRapidOrderTextToOrderUseCase {
|
||||
ParseRapidOrderTextToOrderUseCase({
|
||||
required ClientCreateOrderRepositoryInterface repository,
|
||||
}) : _repository = repository;
|
||||
|
||||
final ClientCreateOrderRepositoryInterface _repository;
|
||||
|
||||
Future<OneTimeOrder> call(String text) async {
|
||||
return _repository.parseRapidOrder(text);
|
||||
}
|
||||
}
|
||||
@@ -136,9 +136,7 @@ class OneTimeOrderBloc extends Bloc<OneTimeOrderEvent, OneTimeOrderState>
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadManagersForHub(
|
||||
String hubId,
|
||||
) async {
|
||||
Future<void> _loadManagersForHub(String hubId) async {
|
||||
final List<OneTimeOrderManagerOption>? managers =
|
||||
await handleErrorWithResult(
|
||||
action: () async {
|
||||
@@ -163,7 +161,9 @@ class OneTimeOrderBloc extends Bloc<OneTimeOrderEvent, OneTimeOrderState>
|
||||
.toList();
|
||||
},
|
||||
onError: (_) {
|
||||
add(const OneTimeOrderManagersLoaded(<OneTimeOrderManagerOption>[]));
|
||||
add(
|
||||
const OneTimeOrderManagersLoaded(<OneTimeOrderManagerOption>[]),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -172,7 +172,6 @@ class OneTimeOrderBloc extends Bloc<OneTimeOrderEvent, OneTimeOrderState>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<void> _onVendorsLoaded(
|
||||
OneTimeOrderVendorsLoaded event,
|
||||
Emitter<OneTimeOrderState> emit,
|
||||
@@ -216,7 +215,6 @@ class OneTimeOrderBloc extends Bloc<OneTimeOrderEvent, OneTimeOrderState>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _onHubChanged(
|
||||
OneTimeOrderHubChanged event,
|
||||
Emitter<OneTimeOrderState> emit,
|
||||
@@ -239,7 +237,6 @@ class OneTimeOrderBloc extends Bloc<OneTimeOrderEvent, OneTimeOrderState>
|
||||
emit(state.copyWith(managers: event.managers));
|
||||
}
|
||||
|
||||
|
||||
void _onEventNameChanged(
|
||||
OneTimeOrderEventNameChanged event,
|
||||
Emitter<OneTimeOrderState> emit,
|
||||
@@ -349,6 +346,45 @@ class OneTimeOrderBloc extends Bloc<OneTimeOrderEvent, OneTimeOrderState>
|
||||
final DateTime? startDate = data['startDate'] as DateTime?;
|
||||
final String? orderId = data['orderId']?.toString();
|
||||
|
||||
// Handle Rapid Order Draft
|
||||
if (data['isRapidDraft'] == true) {
|
||||
final OneTimeOrder? order = data['order'] as OneTimeOrder?;
|
||||
if (order != null) {
|
||||
emit(
|
||||
state.copyWith(
|
||||
eventName: order.eventName ?? '',
|
||||
date: order.date,
|
||||
positions: order.positions,
|
||||
location: order.location,
|
||||
isRapidDraft: true,
|
||||
),
|
||||
);
|
||||
|
||||
// Try to match vendor if available
|
||||
if (order.vendorId != null) {
|
||||
final Vendor? vendor = state.vendors
|
||||
.where((Vendor v) => v.id == order.vendorId)
|
||||
.firstOrNull;
|
||||
if (vendor != null) {
|
||||
emit(state.copyWith(selectedVendor: vendor));
|
||||
await _loadRolesForVendor(vendor.id, emit);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to match hub if available
|
||||
if (order.hub != null) {
|
||||
final OneTimeOrderHubOption? hub = state.hubs
|
||||
.where((OneTimeOrderHubOption h) => h.id == order.hub?.id)
|
||||
.firstOrNull;
|
||||
if (hub != null) {
|
||||
emit(state.copyWith(selectedHub: hub));
|
||||
await _loadManagersForHub(hub.id);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
emit(state.copyWith(eventName: title, date: startDate ?? DateTime.now()));
|
||||
|
||||
if (orderId == null || orderId.isEmpty) return;
|
||||
|
||||
@@ -18,6 +18,7 @@ class OneTimeOrderState extends Equatable {
|
||||
this.roles = const <OneTimeOrderRoleOption>[],
|
||||
this.managers = const <OneTimeOrderManagerOption>[],
|
||||
this.selectedManager,
|
||||
this.isRapidDraft = false,
|
||||
});
|
||||
|
||||
factory OneTimeOrderState.initial() {
|
||||
@@ -47,6 +48,7 @@ class OneTimeOrderState extends Equatable {
|
||||
final List<OneTimeOrderRoleOption> roles;
|
||||
final List<OneTimeOrderManagerOption> managers;
|
||||
final OneTimeOrderManagerOption? selectedManager;
|
||||
final bool isRapidDraft;
|
||||
|
||||
OneTimeOrderState copyWith({
|
||||
DateTime? date,
|
||||
@@ -62,6 +64,7 @@ class OneTimeOrderState extends Equatable {
|
||||
List<OneTimeOrderRoleOption>? roles,
|
||||
List<OneTimeOrderManagerOption>? managers,
|
||||
OneTimeOrderManagerOption? selectedManager,
|
||||
bool? isRapidDraft,
|
||||
}) {
|
||||
return OneTimeOrderState(
|
||||
date: date ?? this.date,
|
||||
@@ -77,6 +80,7 @@ class OneTimeOrderState extends Equatable {
|
||||
roles: roles ?? this.roles,
|
||||
managers: managers ?? this.managers,
|
||||
selectedManager: selectedManager ?? this.selectedManager,
|
||||
isRapidDraft: isRapidDraft ?? this.isRapidDraft,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -109,6 +113,7 @@ class OneTimeOrderState extends Equatable {
|
||||
roles,
|
||||
managers,
|
||||
selectedManager,
|
||||
isRapidDraft,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -171,10 +176,7 @@ class OneTimeOrderRoleOption extends Equatable {
|
||||
}
|
||||
|
||||
class OneTimeOrderManagerOption extends Equatable {
|
||||
const OneTimeOrderManagerOption({
|
||||
required this.id,
|
||||
required this.name,
|
||||
});
|
||||
const OneTimeOrderManagerOption({required this.id, required this.name});
|
||||
|
||||
final String id;
|
||||
final String name;
|
||||
@@ -182,4 +184,3 @@ class OneTimeOrderManagerOption extends Equatable {
|
||||
@override
|
||||
List<Object?> get props => <Object?>[id, name];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:client_create_order/src/domain/arguments/rapid_order_arguments.dart';
|
||||
import 'package:client_create_order/src/domain/usecases/create_rapid_order_usecase.dart';
|
||||
import 'package:client_create_order/src/domain/usecases/parse_rapid_order_usecase.dart';
|
||||
import 'package:client_create_order/src/domain/usecases/transcribe_rapid_order_usecase.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
|
||||
import 'rapid_order_event.dart';
|
||||
import 'rapid_order_state.dart';
|
||||
@@ -9,8 +10,11 @@ import 'rapid_order_state.dart';
|
||||
/// BLoC for managing the rapid (urgent) order creation flow.
|
||||
class RapidOrderBloc extends Bloc<RapidOrderEvent, RapidOrderState>
|
||||
with BlocErrorHandler<RapidOrderState> {
|
||||
RapidOrderBloc(this._createRapidOrderUseCase)
|
||||
: super(
|
||||
RapidOrderBloc(
|
||||
this._transcribeRapidOrderUseCase,
|
||||
this._parseRapidOrderUseCase,
|
||||
this._audioRecorderService,
|
||||
) : super(
|
||||
const RapidOrderInitial(
|
||||
examples: <String>[
|
||||
'"We had a call out. Need 2 cooks ASAP"',
|
||||
@@ -24,7 +28,9 @@ class RapidOrderBloc extends Bloc<RapidOrderEvent, RapidOrderState>
|
||||
on<RapidOrderSubmitted>(_onSubmitted);
|
||||
on<RapidOrderExampleSelected>(_onExampleSelected);
|
||||
}
|
||||
final CreateRapidOrderUseCase _createRapidOrderUseCase;
|
||||
final TranscribeRapidOrderUseCase _transcribeRapidOrderUseCase;
|
||||
final ParseRapidOrderTextToOrderUseCase _parseRapidOrderUseCase;
|
||||
final AudioRecorderService _audioRecorderService;
|
||||
|
||||
void _onMessageChanged(
|
||||
RapidOrderMessageChanged event,
|
||||
@@ -72,10 +78,8 @@ class RapidOrderBloc extends Bloc<RapidOrderEvent, RapidOrderState>
|
||||
await handleError(
|
||||
emit: emit.call,
|
||||
action: () async {
|
||||
await _createRapidOrderUseCase(
|
||||
RapidOrderArguments(description: message),
|
||||
);
|
||||
emit(const RapidOrderSuccess());
|
||||
final OneTimeOrder order = await _parseRapidOrderUseCase(message);
|
||||
emit(RapidOrderParsed(order));
|
||||
},
|
||||
onError: (String errorKey) => RapidOrderFailure(errorKey),
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
|
||||
abstract class RapidOrderState extends Equatable {
|
||||
const RapidOrderState();
|
||||
@@ -48,3 +49,11 @@ class RapidOrderFailure extends RapidOrderState {
|
||||
@override
|
||||
List<Object?> get props => <Object?>[error];
|
||||
}
|
||||
|
||||
class RapidOrderParsed extends RapidOrderState {
|
||||
const RapidOrderParsed(this.order);
|
||||
final OneTimeOrder order;
|
||||
|
||||
@override
|
||||
List<Object?> get props => <Object?>[order];
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ class OneTimeOrderPage extends StatelessWidget {
|
||||
: null,
|
||||
hubManagers: state.managers.map(_mapManager).toList(),
|
||||
isValid: state.isValid,
|
||||
title: state.isRapidDraft ? 'Rapid Order : Verify the order' : null,
|
||||
onEventNameChanged: (String val) =>
|
||||
bloc.add(OneTimeOrderEventNameChanged(val)),
|
||||
onVendorChanged: (Vendor val) =>
|
||||
|
||||
@@ -72,6 +72,13 @@ class _RapidOrderFormState extends State<_RapidOrderForm> {
|
||||
TextPosition(offset: _messageController.text.length),
|
||||
);
|
||||
}
|
||||
} else if (state is RapidOrderParsed) {
|
||||
Modular.to.toCreateOrderOneTime(
|
||||
arguments: <String, dynamic>{
|
||||
'order': state.order,
|
||||
'isRapidDraft': true,
|
||||
},
|
||||
);
|
||||
} else if (state is RapidOrderFailure) {
|
||||
UiSnackbar.show(
|
||||
context,
|
||||
|
||||
@@ -38,6 +38,7 @@ class OneTimeOrderView extends StatelessWidget {
|
||||
required this.onSubmit,
|
||||
required this.onDone,
|
||||
required this.onBack,
|
||||
this.title,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@@ -54,6 +55,7 @@ class OneTimeOrderView extends StatelessWidget {
|
||||
final List<OrderManagerUiModel> hubManagers;
|
||||
final OrderManagerUiModel? selectedHubManager;
|
||||
final bool isValid;
|
||||
final String? title;
|
||||
|
||||
final ValueChanged<String> onEventNameChanged;
|
||||
final ValueChanged<Vendor> onVendorChanged;
|
||||
@@ -61,7 +63,8 @@ class OneTimeOrderView extends StatelessWidget {
|
||||
final ValueChanged<OrderHubUiModel> onHubChanged;
|
||||
final ValueChanged<OrderManagerUiModel?> onHubManagerChanged;
|
||||
final VoidCallback onPositionAdded;
|
||||
final void Function(int index, OrderPositionUiModel position) onPositionUpdated;
|
||||
final void Function(int index, OrderPositionUiModel position)
|
||||
onPositionUpdated;
|
||||
final void Function(int index) onPositionRemoved;
|
||||
final VoidCallback onSubmit;
|
||||
final VoidCallback onDone;
|
||||
@@ -98,7 +101,7 @@ class OneTimeOrderView extends StatelessWidget {
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
OneTimeOrderHeader(
|
||||
title: labels.title,
|
||||
title: title ?? labels.title,
|
||||
subtitle: labels.subtitle,
|
||||
onBack: onBack,
|
||||
),
|
||||
@@ -136,7 +139,7 @@ class OneTimeOrderView extends StatelessWidget {
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
OneTimeOrderHeader(
|
||||
title: labels.title,
|
||||
title: title ?? labels.title,
|
||||
subtitle: labels.subtitle,
|
||||
onBack: onBack,
|
||||
),
|
||||
@@ -220,7 +223,8 @@ class _OneTimeOrderForm extends StatelessWidget {
|
||||
final ValueChanged<OrderHubUiModel> onHubChanged;
|
||||
final ValueChanged<OrderManagerUiModel?> onHubManagerChanged;
|
||||
final VoidCallback onPositionAdded;
|
||||
final void Function(int index, OrderPositionUiModel position) onPositionUpdated;
|
||||
final void Function(int index, OrderPositionUiModel position)
|
||||
onPositionUpdated;
|
||||
final void Function(int index) onPositionRemoved;
|
||||
|
||||
@override
|
||||
@@ -317,10 +321,7 @@ class _OneTimeOrderForm extends StatelessWidget {
|
||||
items: hubs.map((OrderHubUiModel hub) {
|
||||
return DropdownMenuItem<OrderHubUiModel>(
|
||||
value: hub,
|
||||
child: Text(
|
||||
hub.name,
|
||||
style: UiTypography.body2m.textPrimary,
|
||||
),
|
||||
child: Text(hub.name, style: UiTypography.body2m.textPrimary),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
|
||||
@@ -10,6 +10,7 @@ import file_selector_macos
|
||||
import firebase_app_check
|
||||
import firebase_auth
|
||||
import firebase_core
|
||||
import record_macos
|
||||
import shared_preferences_foundation
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
@@ -18,5 +19,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
FLTFirebaseAppCheckPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAppCheckPlugin"))
|
||||
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
|
||||
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||
RecordMacOsPlugin.register(with: registry.registrar(forPlugin: "RecordMacOsPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
}
|
||||
|
||||
@@ -1221,6 +1221,70 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
record:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: record
|
||||
sha256: d5b6b334f3ab02460db6544e08583c942dbf23e3504bf1e14fd4cbe3d9409277
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.0"
|
||||
record_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: record_android
|
||||
sha256: "94783f08403aed33ffb68797bf0715b0812eb852f3c7985644c945faea462ba1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
record_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: record_ios
|
||||
sha256: "8df7c136131bd05efc19256af29b2ba6ccc000ccc2c80d4b6b6d7a8d21a3b5a9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
record_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: record_linux
|
||||
sha256: c31a35cc158cd666fc6395f7f56fc054f31685571684be6b97670a27649ce5c7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
record_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: record_macos
|
||||
sha256: "084902e63fc9c0c224c29203d6c75f0bdf9b6a40536c9d916393c8f4c4256488"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
record_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: record_platform_interface
|
||||
sha256: "8a81dbc4e14e1272a285bbfef6c9136d070a47d9b0d1f40aa6193516253ee2f6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
record_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: record_web
|
||||
sha256: "7e9846981c1f2d111d86f0ae3309071f5bba8b624d1c977316706f08fc31d16d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
record_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: record_windows
|
||||
sha256: "223258060a1d25c62bae18282c16783f28581ec19401d17e56b5205b9f039d78"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.7"
|
||||
rename:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
Reference in New Issue
Block a user