hub & manager issues
This commit is contained in:
BIN
apps/mobile/packages/features/client/orders/analyze.txt
Normal file
BIN
apps/mobile/packages/features/client/orders/analyze.txt
Normal file
Binary file not shown.
BIN
apps/mobile/packages/features/client/orders/analyze_output.txt
Normal file
BIN
apps/mobile/packages/features/client/orders/analyze_output.txt
Normal file
Binary file not shown.
@@ -31,6 +31,8 @@ class OneTimeOrderBloc extends Bloc<OneTimeOrderEvent, OneTimeOrderState>
|
||||
on<OneTimeOrderPositionUpdated>(_onPositionUpdated);
|
||||
on<OneTimeOrderSubmitted>(_onSubmitted);
|
||||
on<OneTimeOrderInitialized>(_onInitialized);
|
||||
on<OneTimeOrderHubManagerChanged>(_onHubManagerChanged);
|
||||
on<OneTimeOrderManagersLoaded>(_onManagersLoaded);
|
||||
|
||||
_loadVendors();
|
||||
_loadHubs();
|
||||
@@ -134,6 +136,43 @@ class OneTimeOrderBloc extends Bloc<OneTimeOrderEvent, OneTimeOrderState>
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadManagersForHub(
|
||||
String hubId,
|
||||
) async {
|
||||
final List<OneTimeOrderManagerOption>? managers =
|
||||
await handleErrorWithResult(
|
||||
action: () async {
|
||||
final fdc.QueryResult<dc.ListTeamMembersData, void> result =
|
||||
await _service.connector.listTeamMembers().execute();
|
||||
|
||||
return result.data.teamMembers
|
||||
.where(
|
||||
(dc.ListTeamMembersTeamMembers member) =>
|
||||
member.teamHubId == hubId &&
|
||||
member.role is dc.Known<dc.TeamMemberRole> &&
|
||||
(member.role as dc.Known<dc.TeamMemberRole>).value ==
|
||||
dc.TeamMemberRole.MANAGER,
|
||||
)
|
||||
.map(
|
||||
(dc.ListTeamMembersTeamMembers member) =>
|
||||
OneTimeOrderManagerOption(
|
||||
id: member.id,
|
||||
name: member.user.fullName ?? 'Unknown',
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
},
|
||||
onError: (_) {
|
||||
add(const OneTimeOrderManagersLoaded(<OneTimeOrderManagerOption>[]));
|
||||
},
|
||||
);
|
||||
|
||||
if (managers != null) {
|
||||
add(OneTimeOrderManagersLoaded(managers));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<void> _onVendorsLoaded(
|
||||
OneTimeOrderVendorsLoaded event,
|
||||
Emitter<OneTimeOrderState> emit,
|
||||
@@ -171,15 +210,36 @@ class OneTimeOrderBloc extends Bloc<OneTimeOrderEvent, OneTimeOrderState>
|
||||
location: selectedHub?.name ?? '',
|
||||
),
|
||||
);
|
||||
|
||||
if (selectedHub != null) {
|
||||
_loadManagersForHub(selectedHub.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _onHubChanged(
|
||||
OneTimeOrderHubChanged event,
|
||||
Emitter<OneTimeOrderState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedHub: event.hub, location: event.hub.name));
|
||||
_loadManagersForHub(event.hub.id);
|
||||
}
|
||||
|
||||
void _onHubManagerChanged(
|
||||
OneTimeOrderHubManagerChanged event,
|
||||
Emitter<OneTimeOrderState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedManager: event.manager));
|
||||
}
|
||||
|
||||
void _onManagersLoaded(
|
||||
OneTimeOrderManagersLoaded event,
|
||||
Emitter<OneTimeOrderState> emit,
|
||||
) {
|
||||
emit(state.copyWith(managers: event.managers));
|
||||
}
|
||||
|
||||
|
||||
void _onEventNameChanged(
|
||||
OneTimeOrderEventNameChanged event,
|
||||
Emitter<OneTimeOrderState> emit,
|
||||
@@ -267,6 +327,7 @@ class OneTimeOrderBloc extends Bloc<OneTimeOrderEvent, OneTimeOrderState>
|
||||
),
|
||||
eventName: state.eventName,
|
||||
vendorId: state.selectedVendor?.id,
|
||||
hubManagerId: state.selectedManager?.id,
|
||||
roleRates: roleRates,
|
||||
);
|
||||
await _createOneTimeOrderUseCase(OneTimeOrderArguments(order: order));
|
||||
|
||||
@@ -89,3 +89,21 @@ class OneTimeOrderInitialized extends OneTimeOrderEvent {
|
||||
@override
|
||||
List<Object?> get props => <Object?>[data];
|
||||
}
|
||||
|
||||
class OneTimeOrderHubManagerChanged extends OneTimeOrderEvent {
|
||||
const OneTimeOrderHubManagerChanged(this.manager);
|
||||
final OneTimeOrderManagerOption? manager;
|
||||
|
||||
@override
|
||||
List<Object?> get props => <Object?>[manager];
|
||||
}
|
||||
|
||||
class OneTimeOrderManagersLoaded extends OneTimeOrderEvent {
|
||||
const OneTimeOrderManagersLoaded(this.managers);
|
||||
final List<OneTimeOrderManagerOption> managers;
|
||||
|
||||
@override
|
||||
List<Object?> get props => <Object?>[managers];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ class OneTimeOrderState extends Equatable {
|
||||
this.hubs = const <OneTimeOrderHubOption>[],
|
||||
this.selectedHub,
|
||||
this.roles = const <OneTimeOrderRoleOption>[],
|
||||
this.managers = const <OneTimeOrderManagerOption>[],
|
||||
this.selectedManager,
|
||||
});
|
||||
|
||||
factory OneTimeOrderState.initial() {
|
||||
@@ -29,6 +31,7 @@ class OneTimeOrderState extends Equatable {
|
||||
vendors: const <Vendor>[],
|
||||
hubs: const <OneTimeOrderHubOption>[],
|
||||
roles: const <OneTimeOrderRoleOption>[],
|
||||
managers: const <OneTimeOrderManagerOption>[],
|
||||
);
|
||||
}
|
||||
final DateTime date;
|
||||
@@ -42,6 +45,8 @@ class OneTimeOrderState extends Equatable {
|
||||
final List<OneTimeOrderHubOption> hubs;
|
||||
final OneTimeOrderHubOption? selectedHub;
|
||||
final List<OneTimeOrderRoleOption> roles;
|
||||
final List<OneTimeOrderManagerOption> managers;
|
||||
final OneTimeOrderManagerOption? selectedManager;
|
||||
|
||||
OneTimeOrderState copyWith({
|
||||
DateTime? date,
|
||||
@@ -55,6 +60,8 @@ class OneTimeOrderState extends Equatable {
|
||||
List<OneTimeOrderHubOption>? hubs,
|
||||
OneTimeOrderHubOption? selectedHub,
|
||||
List<OneTimeOrderRoleOption>? roles,
|
||||
List<OneTimeOrderManagerOption>? managers,
|
||||
OneTimeOrderManagerOption? selectedManager,
|
||||
}) {
|
||||
return OneTimeOrderState(
|
||||
date: date ?? this.date,
|
||||
@@ -68,6 +75,8 @@ class OneTimeOrderState extends Equatable {
|
||||
hubs: hubs ?? this.hubs,
|
||||
selectedHub: selectedHub ?? this.selectedHub,
|
||||
roles: roles ?? this.roles,
|
||||
managers: managers ?? this.managers,
|
||||
selectedManager: selectedManager ?? this.selectedManager,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -98,6 +107,8 @@ class OneTimeOrderState extends Equatable {
|
||||
hubs,
|
||||
selectedHub,
|
||||
roles,
|
||||
managers,
|
||||
selectedManager,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -158,3 +169,17 @@ class OneTimeOrderRoleOption extends Equatable {
|
||||
@override
|
||||
List<Object?> get props => <Object?>[id, name, costPerHour];
|
||||
}
|
||||
|
||||
class OneTimeOrderManagerOption extends Equatable {
|
||||
const OneTimeOrderManagerOption({
|
||||
required this.id,
|
||||
required this.name,
|
||||
});
|
||||
|
||||
final String id;
|
||||
final String name;
|
||||
|
||||
@override
|
||||
List<Object?> get props => <Object?>[id, name];
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ class PermanentOrderBloc extends Bloc<PermanentOrderEvent, PermanentOrderState>
|
||||
on<PermanentOrderPositionUpdated>(_onPositionUpdated);
|
||||
on<PermanentOrderSubmitted>(_onSubmitted);
|
||||
on<PermanentOrderInitialized>(_onInitialized);
|
||||
on<PermanentOrderHubManagerChanged>(_onHubManagerChanged);
|
||||
on<PermanentOrderManagersLoaded>(_onManagersLoaded);
|
||||
|
||||
_loadVendors();
|
||||
_loadHubs();
|
||||
@@ -182,6 +184,10 @@ class PermanentOrderBloc extends Bloc<PermanentOrderEvent, PermanentOrderState>
|
||||
location: selectedHub?.name ?? '',
|
||||
),
|
||||
);
|
||||
|
||||
if (selectedHub != null) {
|
||||
_loadManagersForHub(selectedHub.id, emit);
|
||||
}
|
||||
}
|
||||
|
||||
void _onHubChanged(
|
||||
@@ -189,8 +195,61 @@ class PermanentOrderBloc extends Bloc<PermanentOrderEvent, PermanentOrderState>
|
||||
Emitter<PermanentOrderState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedHub: event.hub, location: event.hub.name));
|
||||
_loadManagersForHub(event.hub.id, emit);
|
||||
}
|
||||
|
||||
void _onHubManagerChanged(
|
||||
PermanentOrderHubManagerChanged event,
|
||||
Emitter<PermanentOrderState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedManager: event.manager));
|
||||
}
|
||||
|
||||
void _onManagersLoaded(
|
||||
PermanentOrderManagersLoaded event,
|
||||
Emitter<PermanentOrderState> emit,
|
||||
) {
|
||||
emit(state.copyWith(managers: event.managers));
|
||||
}
|
||||
|
||||
Future<void> _loadManagersForHub(
|
||||
String hubId,
|
||||
Emitter<PermanentOrderState> emit,
|
||||
) async {
|
||||
final List<PermanentOrderManagerOption>? managers =
|
||||
await handleErrorWithResult(
|
||||
action: () async {
|
||||
final fdc.QueryResult<dc.ListTeamMembersData, void> result =
|
||||
await _service.connector.listTeamMembers().execute();
|
||||
|
||||
return result.data.teamMembers
|
||||
.where(
|
||||
(dc.ListTeamMembersTeamMembers member) =>
|
||||
member.teamHubId == hubId &&
|
||||
member.role is dc.Known<dc.TeamMemberRole> &&
|
||||
(member.role as dc.Known<dc.TeamMemberRole>).value ==
|
||||
dc.TeamMemberRole.MANAGER,
|
||||
)
|
||||
.map(
|
||||
(dc.ListTeamMembersTeamMembers member) =>
|
||||
PermanentOrderManagerOption(
|
||||
id: member.id,
|
||||
name: member.user.fullName ?? 'Unknown',
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
},
|
||||
onError: (_) => emit(
|
||||
state.copyWith(managers: const <PermanentOrderManagerOption>[]),
|
||||
),
|
||||
);
|
||||
|
||||
if (managers != null) {
|
||||
emit(state.copyWith(managers: managers, selectedManager: null));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _onEventNameChanged(
|
||||
PermanentOrderEventNameChanged event,
|
||||
Emitter<PermanentOrderState> emit,
|
||||
@@ -330,6 +389,7 @@ class PermanentOrderBloc extends Bloc<PermanentOrderEvent, PermanentOrderState>
|
||||
),
|
||||
eventName: state.eventName,
|
||||
vendorId: state.selectedVendor?.id,
|
||||
hubManagerId: state.selectedManager?.id,
|
||||
roleRates: roleRates,
|
||||
);
|
||||
await _createPermanentOrderUseCase(order);
|
||||
|
||||
@@ -106,3 +106,20 @@ class PermanentOrderInitialized extends PermanentOrderEvent {
|
||||
@override
|
||||
List<Object?> get props => <Object?>[data];
|
||||
}
|
||||
|
||||
class PermanentOrderHubManagerChanged extends PermanentOrderEvent {
|
||||
const PermanentOrderHubManagerChanged(this.manager);
|
||||
final PermanentOrderManagerOption? manager;
|
||||
|
||||
@override
|
||||
List<Object?> get props => <Object?>[manager];
|
||||
}
|
||||
|
||||
class PermanentOrderManagersLoaded extends PermanentOrderEvent {
|
||||
const PermanentOrderManagersLoaded(this.managers);
|
||||
final List<PermanentOrderManagerOption> managers;
|
||||
|
||||
@override
|
||||
List<Object?> get props => <Object?>[managers];
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ class PermanentOrderState extends Equatable {
|
||||
this.hubs = const <PermanentOrderHubOption>[],
|
||||
this.selectedHub,
|
||||
this.roles = const <PermanentOrderRoleOption>[],
|
||||
this.managers = const <PermanentOrderManagerOption>[],
|
||||
this.selectedManager,
|
||||
});
|
||||
|
||||
factory PermanentOrderState.initial() {
|
||||
@@ -45,6 +47,7 @@ class PermanentOrderState extends Equatable {
|
||||
vendors: const <Vendor>[],
|
||||
hubs: const <PermanentOrderHubOption>[],
|
||||
roles: const <PermanentOrderRoleOption>[],
|
||||
managers: const <PermanentOrderManagerOption>[],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -61,6 +64,8 @@ class PermanentOrderState extends Equatable {
|
||||
final List<PermanentOrderHubOption> hubs;
|
||||
final PermanentOrderHubOption? selectedHub;
|
||||
final List<PermanentOrderRoleOption> roles;
|
||||
final List<PermanentOrderManagerOption> managers;
|
||||
final PermanentOrderManagerOption? selectedManager;
|
||||
|
||||
PermanentOrderState copyWith({
|
||||
DateTime? startDate,
|
||||
@@ -76,6 +81,8 @@ class PermanentOrderState extends Equatable {
|
||||
List<PermanentOrderHubOption>? hubs,
|
||||
PermanentOrderHubOption? selectedHub,
|
||||
List<PermanentOrderRoleOption>? roles,
|
||||
List<PermanentOrderManagerOption>? managers,
|
||||
PermanentOrderManagerOption? selectedManager,
|
||||
}) {
|
||||
return PermanentOrderState(
|
||||
startDate: startDate ?? this.startDate,
|
||||
@@ -91,6 +98,8 @@ class PermanentOrderState extends Equatable {
|
||||
hubs: hubs ?? this.hubs,
|
||||
selectedHub: selectedHub ?? this.selectedHub,
|
||||
roles: roles ?? this.roles,
|
||||
managers: managers ?? this.managers,
|
||||
selectedManager: selectedManager ?? this.selectedManager,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -124,6 +133,8 @@ class PermanentOrderState extends Equatable {
|
||||
hubs,
|
||||
selectedHub,
|
||||
roles,
|
||||
managers,
|
||||
selectedManager,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -185,6 +196,20 @@ class PermanentOrderRoleOption extends Equatable {
|
||||
List<Object?> get props => <Object?>[id, name, costPerHour];
|
||||
}
|
||||
|
||||
class PermanentOrderManagerOption extends Equatable {
|
||||
const PermanentOrderManagerOption({
|
||||
required this.id,
|
||||
required this.name,
|
||||
});
|
||||
|
||||
final String id;
|
||||
final String name;
|
||||
|
||||
@override
|
||||
List<Object?> get props => <Object?>[id, name];
|
||||
}
|
||||
|
||||
|
||||
class PermanentOrderPosition extends Equatable {
|
||||
const PermanentOrderPosition({
|
||||
required this.role,
|
||||
|
||||
@@ -32,6 +32,8 @@ class RecurringOrderBloc extends Bloc<RecurringOrderEvent, RecurringOrderState>
|
||||
on<RecurringOrderPositionUpdated>(_onPositionUpdated);
|
||||
on<RecurringOrderSubmitted>(_onSubmitted);
|
||||
on<RecurringOrderInitialized>(_onInitialized);
|
||||
on<RecurringOrderHubManagerChanged>(_onHubManagerChanged);
|
||||
on<RecurringOrderManagersLoaded>(_onManagersLoaded);
|
||||
|
||||
_loadVendors();
|
||||
_loadHubs();
|
||||
@@ -183,6 +185,10 @@ class RecurringOrderBloc extends Bloc<RecurringOrderEvent, RecurringOrderState>
|
||||
location: selectedHub?.name ?? '',
|
||||
),
|
||||
);
|
||||
|
||||
if (selectedHub != null) {
|
||||
_loadManagersForHub(selectedHub.id, emit);
|
||||
}
|
||||
}
|
||||
|
||||
void _onHubChanged(
|
||||
@@ -190,6 +196,58 @@ class RecurringOrderBloc extends Bloc<RecurringOrderEvent, RecurringOrderState>
|
||||
Emitter<RecurringOrderState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedHub: event.hub, location: event.hub.name));
|
||||
_loadManagersForHub(event.hub.id, emit);
|
||||
}
|
||||
|
||||
void _onHubManagerChanged(
|
||||
RecurringOrderHubManagerChanged event,
|
||||
Emitter<RecurringOrderState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedManager: event.manager));
|
||||
}
|
||||
|
||||
void _onManagersLoaded(
|
||||
RecurringOrderManagersLoaded event,
|
||||
Emitter<RecurringOrderState> emit,
|
||||
) {
|
||||
emit(state.copyWith(managers: event.managers));
|
||||
}
|
||||
|
||||
Future<void> _loadManagersForHub(
|
||||
String hubId,
|
||||
Emitter<RecurringOrderState> emit,
|
||||
) async {
|
||||
final List<RecurringOrderManagerOption>? managers =
|
||||
await handleErrorWithResult(
|
||||
action: () async {
|
||||
final fdc.QueryResult<dc.ListTeamMembersData, void> result =
|
||||
await _service.connector.listTeamMembers().execute();
|
||||
|
||||
return result.data.teamMembers
|
||||
.where(
|
||||
(dc.ListTeamMembersTeamMembers member) =>
|
||||
member.teamHubId == hubId &&
|
||||
member.role is dc.Known<dc.TeamMemberRole> &&
|
||||
(member.role as dc.Known<dc.TeamMemberRole>).value ==
|
||||
dc.TeamMemberRole.MANAGER,
|
||||
)
|
||||
.map(
|
||||
(dc.ListTeamMembersTeamMembers member) =>
|
||||
RecurringOrderManagerOption(
|
||||
id: member.id,
|
||||
name: member.user.fullName ?? 'Unknown',
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
},
|
||||
onError: (_) => emit(
|
||||
state.copyWith(managers: const <RecurringOrderManagerOption>[]),
|
||||
),
|
||||
);
|
||||
|
||||
if (managers != null) {
|
||||
emit(state.copyWith(managers: managers, selectedManager: null));
|
||||
}
|
||||
}
|
||||
|
||||
void _onEventNameChanged(
|
||||
@@ -349,6 +407,7 @@ class RecurringOrderBloc extends Bloc<RecurringOrderEvent, RecurringOrderState>
|
||||
),
|
||||
eventName: state.eventName,
|
||||
vendorId: state.selectedVendor?.id,
|
||||
hubManagerId: state.selectedManager?.id,
|
||||
roleRates: roleRates,
|
||||
);
|
||||
await _createRecurringOrderUseCase(order);
|
||||
|
||||
@@ -115,3 +115,20 @@ class RecurringOrderInitialized extends RecurringOrderEvent {
|
||||
@override
|
||||
List<Object?> get props => <Object?>[data];
|
||||
}
|
||||
|
||||
class RecurringOrderHubManagerChanged extends RecurringOrderEvent {
|
||||
const RecurringOrderHubManagerChanged(this.manager);
|
||||
final RecurringOrderManagerOption? manager;
|
||||
|
||||
@override
|
||||
List<Object?> get props => <Object?>[manager];
|
||||
}
|
||||
|
||||
class RecurringOrderManagersLoaded extends RecurringOrderEvent {
|
||||
const RecurringOrderManagersLoaded(this.managers);
|
||||
final List<RecurringOrderManagerOption> managers;
|
||||
|
||||
@override
|
||||
List<Object?> get props => <Object?>[managers];
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ class RecurringOrderState extends Equatable {
|
||||
this.hubs = const <RecurringOrderHubOption>[],
|
||||
this.selectedHub,
|
||||
this.roles = const <RecurringOrderRoleOption>[],
|
||||
this.managers = const <RecurringOrderManagerOption>[],
|
||||
this.selectedManager,
|
||||
});
|
||||
|
||||
factory RecurringOrderState.initial() {
|
||||
@@ -47,6 +49,7 @@ class RecurringOrderState extends Equatable {
|
||||
vendors: const <Vendor>[],
|
||||
hubs: const <RecurringOrderHubOption>[],
|
||||
roles: const <RecurringOrderRoleOption>[],
|
||||
managers: const <RecurringOrderManagerOption>[],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -64,6 +67,8 @@ class RecurringOrderState extends Equatable {
|
||||
final List<RecurringOrderHubOption> hubs;
|
||||
final RecurringOrderHubOption? selectedHub;
|
||||
final List<RecurringOrderRoleOption> roles;
|
||||
final List<RecurringOrderManagerOption> managers;
|
||||
final RecurringOrderManagerOption? selectedManager;
|
||||
|
||||
RecurringOrderState copyWith({
|
||||
DateTime? startDate,
|
||||
@@ -80,6 +85,8 @@ class RecurringOrderState extends Equatable {
|
||||
List<RecurringOrderHubOption>? hubs,
|
||||
RecurringOrderHubOption? selectedHub,
|
||||
List<RecurringOrderRoleOption>? roles,
|
||||
List<RecurringOrderManagerOption>? managers,
|
||||
RecurringOrderManagerOption? selectedManager,
|
||||
}) {
|
||||
return RecurringOrderState(
|
||||
startDate: startDate ?? this.startDate,
|
||||
@@ -96,6 +103,8 @@ class RecurringOrderState extends Equatable {
|
||||
hubs: hubs ?? this.hubs,
|
||||
selectedHub: selectedHub ?? this.selectedHub,
|
||||
roles: roles ?? this.roles,
|
||||
managers: managers ?? this.managers,
|
||||
selectedManager: selectedManager ?? this.selectedManager,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -132,6 +141,8 @@ class RecurringOrderState extends Equatable {
|
||||
hubs,
|
||||
selectedHub,
|
||||
roles,
|
||||
managers,
|
||||
selectedManager,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -193,6 +204,20 @@ class RecurringOrderRoleOption extends Equatable {
|
||||
List<Object?> get props => <Object?>[id, name, costPerHour];
|
||||
}
|
||||
|
||||
class RecurringOrderManagerOption extends Equatable {
|
||||
const RecurringOrderManagerOption({
|
||||
required this.id,
|
||||
required this.name,
|
||||
});
|
||||
|
||||
final String id;
|
||||
final String name;
|
||||
|
||||
@override
|
||||
List<Object?> get props => <Object?>[id, name];
|
||||
}
|
||||
|
||||
|
||||
class RecurringOrderPosition extends Equatable {
|
||||
const RecurringOrderPosition({
|
||||
required this.role,
|
||||
|
||||
@@ -48,6 +48,10 @@ class OneTimeOrderPage extends StatelessWidget {
|
||||
hubs: state.hubs.map(_mapHub).toList(),
|
||||
positions: state.positions.map(_mapPosition).toList(),
|
||||
roles: state.roles.map(_mapRole).toList(),
|
||||
selectedHubManager: state.selectedManager != null
|
||||
? _mapManager(state.selectedManager!)
|
||||
: null,
|
||||
hubManagers: state.managers.map(_mapManager).toList(),
|
||||
isValid: state.isValid,
|
||||
onEventNameChanged: (String val) =>
|
||||
bloc.add(OneTimeOrderEventNameChanged(val)),
|
||||
@@ -61,6 +65,17 @@ class OneTimeOrderPage extends StatelessWidget {
|
||||
);
|
||||
bloc.add(OneTimeOrderHubChanged(originalHub));
|
||||
},
|
||||
onHubManagerChanged: (OrderManagerUiModel? val) {
|
||||
if (val == null) {
|
||||
bloc.add(const OneTimeOrderHubManagerChanged(null));
|
||||
return;
|
||||
}
|
||||
final OneTimeOrderManagerOption original =
|
||||
state.managers.firstWhere(
|
||||
(OneTimeOrderManagerOption m) => m.id == val.id,
|
||||
);
|
||||
bloc.add(OneTimeOrderHubManagerChanged(original));
|
||||
},
|
||||
onPositionAdded: () => bloc.add(const OneTimeOrderPositionAdded()),
|
||||
onPositionUpdated: (int index, OrderPositionUiModel val) {
|
||||
final OneTimeOrderPosition original = state.positions[index];
|
||||
@@ -130,4 +145,9 @@ class OneTimeOrderPage extends StatelessWidget {
|
||||
lunchBreak: pos.lunchBreak,
|
||||
);
|
||||
}
|
||||
|
||||
OrderManagerUiModel _mapManager(OneTimeOrderManagerOption manager) {
|
||||
return OrderManagerUiModel(id: manager.id, name: manager.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,10 @@ class PermanentOrderPage extends StatelessWidget {
|
||||
? _mapHub(state.selectedHub!)
|
||||
: null,
|
||||
hubs: state.hubs.map(_mapHub).toList(),
|
||||
hubManagers: state.managers.map(_mapManager).toList(),
|
||||
selectedHubManager: state.selectedManager != null
|
||||
? _mapManager(state.selectedManager!)
|
||||
: null,
|
||||
positions: state.positions.map(_mapPosition).toList(),
|
||||
roles: state.roles.map(_mapRole).toList(),
|
||||
isValid: state.isValid,
|
||||
@@ -59,6 +63,17 @@ class PermanentOrderPage extends StatelessWidget {
|
||||
);
|
||||
bloc.add(PermanentOrderHubChanged(originalHub));
|
||||
},
|
||||
onHubManagerChanged: (OrderManagerUiModel? val) {
|
||||
if (val == null) {
|
||||
bloc.add(const PermanentOrderHubManagerChanged(null));
|
||||
return;
|
||||
}
|
||||
final PermanentOrderManagerOption original =
|
||||
state.managers.firstWhere(
|
||||
(PermanentOrderManagerOption m) => m.id == val.id,
|
||||
);
|
||||
bloc.add(PermanentOrderHubManagerChanged(original));
|
||||
},
|
||||
onPositionAdded: () =>
|
||||
bloc.add(const PermanentOrderPositionAdded()),
|
||||
onPositionUpdated: (int index, OrderPositionUiModel val) {
|
||||
@@ -181,4 +196,8 @@ class PermanentOrderPage extends StatelessWidget {
|
||||
lunchBreak: pos.lunchBreak ?? 'NO_BREAK',
|
||||
);
|
||||
}
|
||||
|
||||
OrderManagerUiModel _mapManager(PermanentOrderManagerOption manager) {
|
||||
return OrderManagerUiModel(id: manager.id, name: manager.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,10 @@ class RecurringOrderPage extends StatelessWidget {
|
||||
? _mapHub(state.selectedHub!)
|
||||
: null,
|
||||
hubs: state.hubs.map(_mapHub).toList(),
|
||||
hubManagers: state.managers.map(_mapManager).toList(),
|
||||
selectedHubManager: state.selectedManager != null
|
||||
? _mapManager(state.selectedManager!)
|
||||
: null,
|
||||
positions: state.positions.map(_mapPosition).toList(),
|
||||
roles: state.roles.map(_mapRole).toList(),
|
||||
isValid: state.isValid,
|
||||
@@ -62,6 +66,17 @@ class RecurringOrderPage extends StatelessWidget {
|
||||
);
|
||||
bloc.add(RecurringOrderHubChanged(originalHub));
|
||||
},
|
||||
onHubManagerChanged: (OrderManagerUiModel? val) {
|
||||
if (val == null) {
|
||||
bloc.add(const RecurringOrderHubManagerChanged(null));
|
||||
return;
|
||||
}
|
||||
final RecurringOrderManagerOption original =
|
||||
state.managers.firstWhere(
|
||||
(RecurringOrderManagerOption m) => m.id == val.id,
|
||||
);
|
||||
bloc.add(RecurringOrderHubManagerChanged(original));
|
||||
},
|
||||
onPositionAdded: () =>
|
||||
bloc.add(const RecurringOrderPositionAdded()),
|
||||
onPositionUpdated: (int index, OrderPositionUiModel val) {
|
||||
@@ -193,4 +208,8 @@ class RecurringOrderPage extends StatelessWidget {
|
||||
lunchBreak: pos.lunchBreak ?? 'NO_BREAK',
|
||||
);
|
||||
}
|
||||
|
||||
OrderManagerUiModel _mapManager(RecurringOrderManagerOption manager) {
|
||||
return OrderManagerUiModel(id: manager.id, name: manager.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'order_ui_models.dart';
|
||||
|
||||
class HubManagerSelector extends StatelessWidget {
|
||||
const HubManagerSelector({
|
||||
required this.managers,
|
||||
required this.selectedManager,
|
||||
required this.onChanged,
|
||||
required this.hintText,
|
||||
required this.label,
|
||||
this.description,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final List<OrderManagerUiModel> managers;
|
||||
final OrderManagerUiModel? selectedManager;
|
||||
final ValueChanged<OrderManagerUiModel?> onChanged;
|
||||
final String hintText;
|
||||
final String label;
|
||||
final String? description;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
label,
|
||||
style: UiTypography.body1m.textPrimary,
|
||||
),
|
||||
if (description != null) ...<Widget>[
|
||||
const SizedBox(height: UiConstants.space2),
|
||||
Text(description!, style: UiTypography.body2r.textSecondary),
|
||||
],
|
||||
const SizedBox(height: UiConstants.space2),
|
||||
InkWell(
|
||||
onTap: () => _showSelector(context),
|
||||
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: UiConstants.space4,
|
||||
vertical: 14,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: UiColors.white,
|
||||
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
||||
border: Border.all(
|
||||
color: selectedManager != null ? UiColors.primary : UiColors.border,
|
||||
width: selectedManager != null ? 2 : 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Icon(
|
||||
UiIcons.user,
|
||||
color: selectedManager != null
|
||||
? UiColors.primary
|
||||
: UiColors.iconSecondary,
|
||||
size: 20,
|
||||
),
|
||||
const SizedBox(width: UiConstants.space3),
|
||||
Text(
|
||||
selectedManager?.name ?? hintText,
|
||||
style: selectedManager != null
|
||||
? UiTypography.body1r.textPrimary
|
||||
: UiTypography.body2r.textPlaceholder,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
const Icon(
|
||||
Icons.keyboard_arrow_down,
|
||||
color: UiColors.iconSecondary,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _showSelector(BuildContext context) async {
|
||||
final OrderManagerUiModel? selected = await showDialog<OrderManagerUiModel>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
||||
),
|
||||
title: Text(
|
||||
label,
|
||||
style: UiTypography.headline3m.textPrimary,
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||
content: SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxHeight: 400),
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: managers.isEmpty ? 2 : managers.length + 1,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
if (managers.isEmpty) {
|
||||
if (index == 0) {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 8),
|
||||
child: Text('No hub managers available'),
|
||||
);
|
||||
}
|
||||
return ListTile(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
title: Text('None', style: UiTypography.body1m.textSecondary),
|
||||
onTap: () => Navigator.of(context).pop(
|
||||
const OrderManagerUiModel(id: 'NONE', name: 'None'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (index == managers.length) {
|
||||
return ListTile(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
title: Text('None', style: UiTypography.body1m.textSecondary),
|
||||
onTap: () => Navigator.of(context).pop(
|
||||
const OrderManagerUiModel(id: 'NONE', name: 'None'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final OrderManagerUiModel manager = managers[index];
|
||||
return ListTile(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8),
|
||||
title: Text(manager.name, style: UiTypography.body1m.textPrimary),
|
||||
subtitle: manager.phone != null
|
||||
? Text(manager.phone!, style: UiTypography.body2r.textSecondary)
|
||||
: null,
|
||||
onTap: () => Navigator.of(context).pop(manager),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (selected != null) {
|
||||
if (selected.id == 'NONE') {
|
||||
onChanged(null);
|
||||
} else {
|
||||
onChanged(selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import '../order_ui_models.dart';
|
||||
import '../hub_manager_selector.dart';
|
||||
import 'one_time_order_date_picker.dart';
|
||||
import 'one_time_order_event_name_input.dart';
|
||||
import 'one_time_order_header.dart';
|
||||
@@ -23,11 +24,14 @@ class OneTimeOrderView extends StatelessWidget {
|
||||
required this.hubs,
|
||||
required this.positions,
|
||||
required this.roles,
|
||||
required this.hubManagers,
|
||||
required this.selectedHubManager,
|
||||
required this.isValid,
|
||||
required this.onEventNameChanged,
|
||||
required this.onVendorChanged,
|
||||
required this.onDateChanged,
|
||||
required this.onHubChanged,
|
||||
required this.onHubManagerChanged,
|
||||
required this.onPositionAdded,
|
||||
required this.onPositionUpdated,
|
||||
required this.onPositionRemoved,
|
||||
@@ -47,12 +51,15 @@ class OneTimeOrderView extends StatelessWidget {
|
||||
final List<OrderHubUiModel> hubs;
|
||||
final List<OrderPositionUiModel> positions;
|
||||
final List<OrderRoleUiModel> roles;
|
||||
final List<OrderManagerUiModel> hubManagers;
|
||||
final OrderManagerUiModel? selectedHubManager;
|
||||
final bool isValid;
|
||||
|
||||
final ValueChanged<String> onEventNameChanged;
|
||||
final ValueChanged<Vendor> onVendorChanged;
|
||||
final ValueChanged<DateTime> onDateChanged;
|
||||
final ValueChanged<OrderHubUiModel> onHubChanged;
|
||||
final ValueChanged<OrderManagerUiModel?> onHubManagerChanged;
|
||||
final VoidCallback onPositionAdded;
|
||||
final void Function(int index, OrderPositionUiModel position) onPositionUpdated;
|
||||
final void Function(int index) onPositionRemoved;
|
||||
@@ -143,12 +150,15 @@ class OneTimeOrderView extends StatelessWidget {
|
||||
date: date,
|
||||
selectedHub: selectedHub,
|
||||
hubs: hubs,
|
||||
selectedHubManager: selectedHubManager,
|
||||
hubManagers: hubManagers,
|
||||
positions: positions,
|
||||
roles: roles,
|
||||
onEventNameChanged: onEventNameChanged,
|
||||
onVendorChanged: onVendorChanged,
|
||||
onDateChanged: onDateChanged,
|
||||
onHubChanged: onHubChanged,
|
||||
onHubManagerChanged: onHubManagerChanged,
|
||||
onPositionAdded: onPositionAdded,
|
||||
onPositionUpdated: onPositionUpdated,
|
||||
onPositionRemoved: onPositionRemoved,
|
||||
@@ -179,12 +189,15 @@ class _OneTimeOrderForm extends StatelessWidget {
|
||||
required this.date,
|
||||
required this.selectedHub,
|
||||
required this.hubs,
|
||||
required this.selectedHubManager,
|
||||
required this.hubManagers,
|
||||
required this.positions,
|
||||
required this.roles,
|
||||
required this.onEventNameChanged,
|
||||
required this.onVendorChanged,
|
||||
required this.onDateChanged,
|
||||
required this.onHubChanged,
|
||||
required this.onHubManagerChanged,
|
||||
required this.onPositionAdded,
|
||||
required this.onPositionUpdated,
|
||||
required this.onPositionRemoved,
|
||||
@@ -196,6 +209,8 @@ class _OneTimeOrderForm extends StatelessWidget {
|
||||
final DateTime date;
|
||||
final OrderHubUiModel? selectedHub;
|
||||
final List<OrderHubUiModel> hubs;
|
||||
final OrderManagerUiModel? selectedHubManager;
|
||||
final List<OrderManagerUiModel> hubManagers;
|
||||
final List<OrderPositionUiModel> positions;
|
||||
final List<OrderRoleUiModel> roles;
|
||||
|
||||
@@ -203,6 +218,7 @@ class _OneTimeOrderForm extends StatelessWidget {
|
||||
final ValueChanged<Vendor> onVendorChanged;
|
||||
final ValueChanged<DateTime> onDateChanged;
|
||||
final ValueChanged<OrderHubUiModel> onHubChanged;
|
||||
final ValueChanged<OrderManagerUiModel?> onHubManagerChanged;
|
||||
final VoidCallback onPositionAdded;
|
||||
final void Function(int index, OrderPositionUiModel position) onPositionUpdated;
|
||||
final void Function(int index) onPositionRemoved;
|
||||
@@ -310,6 +326,16 @@ class _OneTimeOrderForm extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: UiConstants.space4),
|
||||
|
||||
HubManagerSelector(
|
||||
label: labels.hub_manager_label,
|
||||
description: labels.hub_manager_desc,
|
||||
hintText: labels.hub_manager_hint,
|
||||
managers: hubManagers,
|
||||
selectedManager: selectedHubManager,
|
||||
onChanged: onHubManagerChanged,
|
||||
),
|
||||
const SizedBox(height: UiConstants.space6),
|
||||
|
||||
OneTimeOrderSectionHeader(
|
||||
|
||||
@@ -94,3 +94,19 @@ class OrderPositionUiModel extends Equatable {
|
||||
@override
|
||||
List<Object?> get props => <Object?>[role, count, startTime, endTime, lunchBreak];
|
||||
}
|
||||
|
||||
class OrderManagerUiModel extends Equatable {
|
||||
const OrderManagerUiModel({
|
||||
required this.id,
|
||||
required this.name,
|
||||
this.phone,
|
||||
});
|
||||
|
||||
final String id;
|
||||
final String name;
|
||||
final String? phone;
|
||||
|
||||
@override
|
||||
List<Object?> get props => <Object?>[id, name, phone];
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:krow_domain/krow_domain.dart' show Vendor;
|
||||
import '../order_ui_models.dart';
|
||||
import '../hub_manager_selector.dart';
|
||||
import 'permanent_order_date_picker.dart';
|
||||
import 'permanent_order_event_name_input.dart';
|
||||
import 'permanent_order_header.dart';
|
||||
@@ -24,12 +25,15 @@ class PermanentOrderView extends StatelessWidget {
|
||||
required this.hubs,
|
||||
required this.positions,
|
||||
required this.roles,
|
||||
required this.hubManagers,
|
||||
required this.selectedHubManager,
|
||||
required this.isValid,
|
||||
required this.onEventNameChanged,
|
||||
required this.onVendorChanged,
|
||||
required this.onStartDateChanged,
|
||||
required this.onDayToggled,
|
||||
required this.onHubChanged,
|
||||
required this.onHubManagerChanged,
|
||||
required this.onPositionAdded,
|
||||
required this.onPositionUpdated,
|
||||
required this.onPositionRemoved,
|
||||
@@ -48,6 +52,8 @@ class PermanentOrderView extends StatelessWidget {
|
||||
final List<String> permanentDays;
|
||||
final OrderHubUiModel? selectedHub;
|
||||
final List<OrderHubUiModel> hubs;
|
||||
final OrderManagerUiModel? selectedHubManager;
|
||||
final List<OrderManagerUiModel> hubManagers;
|
||||
final List<OrderPositionUiModel> positions;
|
||||
final List<OrderRoleUiModel> roles;
|
||||
final bool isValid;
|
||||
@@ -57,6 +63,7 @@ class PermanentOrderView extends StatelessWidget {
|
||||
final ValueChanged<DateTime> onStartDateChanged;
|
||||
final ValueChanged<int> onDayToggled;
|
||||
final ValueChanged<OrderHubUiModel> onHubChanged;
|
||||
final ValueChanged<OrderManagerUiModel?> onHubManagerChanged;
|
||||
final VoidCallback onPositionAdded;
|
||||
final void Function(int index, OrderPositionUiModel position) onPositionUpdated;
|
||||
final void Function(int index) onPositionRemoved;
|
||||
@@ -156,9 +163,12 @@ class PermanentOrderView extends StatelessWidget {
|
||||
onStartDateChanged: onStartDateChanged,
|
||||
onDayToggled: onDayToggled,
|
||||
onHubChanged: onHubChanged,
|
||||
onHubManagerChanged: onHubManagerChanged,
|
||||
onPositionAdded: onPositionAdded,
|
||||
onPositionUpdated: onPositionUpdated,
|
||||
onPositionRemoved: onPositionRemoved,
|
||||
hubManagers: hubManagers,
|
||||
selectedHubManager: selectedHubManager,
|
||||
),
|
||||
if (status == OrderFormStatus.loading)
|
||||
const Center(child: CircularProgressIndicator()),
|
||||
@@ -194,9 +204,12 @@ class _PermanentOrderForm extends StatelessWidget {
|
||||
required this.onStartDateChanged,
|
||||
required this.onDayToggled,
|
||||
required this.onHubChanged,
|
||||
required this.onHubManagerChanged,
|
||||
required this.onPositionAdded,
|
||||
required this.onPositionUpdated,
|
||||
required this.onPositionRemoved,
|
||||
required this.hubManagers,
|
||||
required this.selectedHubManager,
|
||||
});
|
||||
|
||||
final String eventName;
|
||||
@@ -214,10 +227,14 @@ class _PermanentOrderForm extends StatelessWidget {
|
||||
final ValueChanged<DateTime> onStartDateChanged;
|
||||
final ValueChanged<int> onDayToggled;
|
||||
final ValueChanged<OrderHubUiModel> onHubChanged;
|
||||
final ValueChanged<OrderManagerUiModel?> onHubManagerChanged;
|
||||
final VoidCallback onPositionAdded;
|
||||
final void Function(int index, OrderPositionUiModel position) onPositionUpdated;
|
||||
final void Function(int index) onPositionRemoved;
|
||||
|
||||
final List<OrderManagerUiModel> hubManagers;
|
||||
final OrderManagerUiModel? selectedHubManager;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final TranslationsClientCreateOrderPermanentEn labels =
|
||||
@@ -331,6 +348,16 @@ class _PermanentOrderForm extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: UiConstants.space4),
|
||||
|
||||
HubManagerSelector(
|
||||
label: oneTimeLabels.hub_manager_label,
|
||||
description: oneTimeLabels.hub_manager_desc,
|
||||
hintText: oneTimeLabels.hub_manager_hint,
|
||||
managers: hubManagers,
|
||||
selectedManager: selectedHubManager,
|
||||
onChanged: onHubManagerChanged,
|
||||
),
|
||||
const SizedBox(height: UiConstants.space6),
|
||||
|
||||
PermanentOrderSectionHeader(
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:krow_domain/krow_domain.dart' show Vendor;
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../order_ui_models.dart';
|
||||
import '../hub_manager_selector.dart';
|
||||
import 'recurring_order_date_picker.dart';
|
||||
import 'recurring_order_event_name_input.dart';
|
||||
import 'recurring_order_header.dart';
|
||||
@@ -25,6 +26,8 @@ class RecurringOrderView extends StatelessWidget {
|
||||
required this.hubs,
|
||||
required this.positions,
|
||||
required this.roles,
|
||||
required this.hubManagers,
|
||||
required this.selectedHubManager,
|
||||
required this.isValid,
|
||||
required this.onEventNameChanged,
|
||||
required this.onVendorChanged,
|
||||
@@ -32,6 +35,7 @@ class RecurringOrderView extends StatelessWidget {
|
||||
required this.onEndDateChanged,
|
||||
required this.onDayToggled,
|
||||
required this.onHubChanged,
|
||||
required this.onHubManagerChanged,
|
||||
required this.onPositionAdded,
|
||||
required this.onPositionUpdated,
|
||||
required this.onPositionRemoved,
|
||||
@@ -51,6 +55,8 @@ class RecurringOrderView extends StatelessWidget {
|
||||
final List<String> recurringDays;
|
||||
final OrderHubUiModel? selectedHub;
|
||||
final List<OrderHubUiModel> hubs;
|
||||
final OrderManagerUiModel? selectedHubManager;
|
||||
final List<OrderManagerUiModel> hubManagers;
|
||||
final List<OrderPositionUiModel> positions;
|
||||
final List<OrderRoleUiModel> roles;
|
||||
final bool isValid;
|
||||
@@ -61,6 +67,7 @@ class RecurringOrderView extends StatelessWidget {
|
||||
final ValueChanged<DateTime> onEndDateChanged;
|
||||
final ValueChanged<int> onDayToggled;
|
||||
final ValueChanged<OrderHubUiModel> onHubChanged;
|
||||
final ValueChanged<OrderManagerUiModel?> onHubManagerChanged;
|
||||
final VoidCallback onPositionAdded;
|
||||
final void Function(int index, OrderPositionUiModel position) onPositionUpdated;
|
||||
final void Function(int index) onPositionRemoved;
|
||||
@@ -165,9 +172,12 @@ class RecurringOrderView extends StatelessWidget {
|
||||
onEndDateChanged: onEndDateChanged,
|
||||
onDayToggled: onDayToggled,
|
||||
onHubChanged: onHubChanged,
|
||||
onHubManagerChanged: onHubManagerChanged,
|
||||
onPositionAdded: onPositionAdded,
|
||||
onPositionUpdated: onPositionUpdated,
|
||||
onPositionRemoved: onPositionRemoved,
|
||||
hubManagers: hubManagers,
|
||||
selectedHubManager: selectedHubManager,
|
||||
),
|
||||
if (status == OrderFormStatus.loading)
|
||||
const Center(child: CircularProgressIndicator()),
|
||||
@@ -205,9 +215,12 @@ class _RecurringOrderForm extends StatelessWidget {
|
||||
required this.onEndDateChanged,
|
||||
required this.onDayToggled,
|
||||
required this.onHubChanged,
|
||||
required this.onHubManagerChanged,
|
||||
required this.onPositionAdded,
|
||||
required this.onPositionUpdated,
|
||||
required this.onPositionRemoved,
|
||||
required this.hubManagers,
|
||||
required this.selectedHubManager,
|
||||
});
|
||||
|
||||
final String eventName;
|
||||
@@ -227,10 +240,15 @@ class _RecurringOrderForm extends StatelessWidget {
|
||||
final ValueChanged<DateTime> onEndDateChanged;
|
||||
final ValueChanged<int> onDayToggled;
|
||||
final ValueChanged<OrderHubUiModel> onHubChanged;
|
||||
final ValueChanged<OrderManagerUiModel?> onHubManagerChanged;
|
||||
final VoidCallback onPositionAdded;
|
||||
final void Function(int index, OrderPositionUiModel position) onPositionUpdated;
|
||||
final void Function(int index) onPositionRemoved;
|
||||
|
||||
final List<OrderManagerUiModel> hubManagers;
|
||||
final OrderManagerUiModel? selectedHubManager;
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final TranslationsClientCreateOrderRecurringEn labels =
|
||||
@@ -351,6 +369,16 @@ class _RecurringOrderForm extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: UiConstants.space4),
|
||||
|
||||
HubManagerSelector(
|
||||
label: oneTimeLabels.hub_manager_label,
|
||||
description: oneTimeLabels.hub_manager_desc,
|
||||
hintText: oneTimeLabels.hub_manager_hint,
|
||||
managers: hubManagers,
|
||||
selectedManager: selectedHubManager,
|
||||
onChanged: onHubManagerChanged,
|
||||
),
|
||||
const SizedBox(height: UiConstants.space6),
|
||||
|
||||
RecurringOrderSectionHeader(
|
||||
|
||||
@@ -57,6 +57,9 @@ class OrderEditSheetState extends State<OrderEditSheet> {
|
||||
const <dc.ListTeamHubsByOwnerIdTeamHubs>[];
|
||||
dc.ListTeamHubsByOwnerIdTeamHubs? _selectedHub;
|
||||
|
||||
List<dc.ListTeamMembersTeamMembers> _managers = const <dc.ListTeamMembersTeamMembers>[];
|
||||
dc.ListTeamMembersTeamMembers? _selectedManager;
|
||||
|
||||
String? _shiftId;
|
||||
List<_ShiftRoleKey> _originalShiftRoles = const <_ShiftRoleKey>[];
|
||||
|
||||
@@ -246,6 +249,9 @@ class OrderEditSheetState extends State<OrderEditSheet> {
|
||||
}
|
||||
});
|
||||
}
|
||||
if (selected != null) {
|
||||
await _loadManagersForHub(selected.id, widget.order.hubManagerId);
|
||||
}
|
||||
} catch (_) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
@@ -331,6 +337,47 @@ class OrderEditSheetState extends State<OrderEditSheet> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadManagersForHub(String hubId, [String? preselectedId]) async {
|
||||
try {
|
||||
final QueryResult<dc.ListTeamMembersData, void> result =
|
||||
await _dataConnect.listTeamMembers().execute();
|
||||
|
||||
final List<dc.ListTeamMembersTeamMembers> hubManagers = result.data.teamMembers
|
||||
.where(
|
||||
(dc.ListTeamMembersTeamMembers member) =>
|
||||
member.teamHubId == hubId &&
|
||||
member.role is dc.Known<dc.TeamMemberRole> &&
|
||||
(member.role as dc.Known<dc.TeamMemberRole>).value ==
|
||||
dc.TeamMemberRole.MANAGER,
|
||||
)
|
||||
.toList();
|
||||
|
||||
dc.ListTeamMembersTeamMembers? selected;
|
||||
if (preselectedId != null && preselectedId.isNotEmpty) {
|
||||
for (final dc.ListTeamMembersTeamMembers m in hubManagers) {
|
||||
if (m.id == preselectedId) {
|
||||
selected = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_managers = hubManagers;
|
||||
_selectedManager = selected;
|
||||
});
|
||||
}
|
||||
} catch (_) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_managers = const <dc.ListTeamMembersTeamMembers>[];
|
||||
_selectedManager = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> _emptyPosition() {
|
||||
return <String, dynamic>{
|
||||
'shiftId': _shiftId,
|
||||
@@ -744,6 +791,10 @@ class OrderEditSheetState extends State<OrderEditSheet> {
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: UiConstants.space4),
|
||||
|
||||
_buildHubManagerSelector(),
|
||||
|
||||
const SizedBox(height: UiConstants.space6),
|
||||
|
||||
Row(
|
||||
@@ -807,6 +858,130 @@ class OrderEditSheetState extends State<OrderEditSheet> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHubManagerSelector() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
_buildSectionHeader('SHIFT CONTACT'),
|
||||
Text('On-site manager or supervisor for this shift', style: UiTypography.body2r.textSecondary),
|
||||
const SizedBox(height: UiConstants.space2),
|
||||
InkWell(
|
||||
onTap: () => _showHubManagerSelector(),
|
||||
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: UiConstants.space4,
|
||||
vertical: 14,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: UiColors.white,
|
||||
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
||||
border: Border.all(
|
||||
color: _selectedManager != null ? UiColors.primary : UiColors.border,
|
||||
width: _selectedManager != null ? 2 : 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Icon(
|
||||
UiIcons.user,
|
||||
color: _selectedManager != null
|
||||
? UiColors.primary
|
||||
: UiColors.iconSecondary,
|
||||
size: 20,
|
||||
),
|
||||
const SizedBox(width: UiConstants.space3),
|
||||
Text(
|
||||
_selectedManager?.user.fullName ?? 'Select Contact',
|
||||
style: _selectedManager != null
|
||||
? UiTypography.body1r.textPrimary
|
||||
: UiTypography.body2r.textPlaceholder,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
const Icon(
|
||||
Icons.keyboard_arrow_down,
|
||||
color: UiColors.iconSecondary,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _showHubManagerSelector() async {
|
||||
final dc.ListTeamMembersTeamMembers? selected = await showDialog<dc.ListTeamMembersTeamMembers?>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
||||
),
|
||||
title: Text(
|
||||
'Shift Contact',
|
||||
style: UiTypography.headline3m.textPrimary,
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||
content: SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxHeight: 400),
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: _managers.isEmpty ? 2 : _managers.length + 1,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
if (_managers.isEmpty) {
|
||||
if (index == 0) {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 8),
|
||||
child: Text('No hub managers available'),
|
||||
);
|
||||
}
|
||||
return ListTile(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
title: Text('None', style: UiTypography.body1m.textSecondary),
|
||||
onTap: () => Navigator.of(context).pop(null),
|
||||
);
|
||||
}
|
||||
|
||||
if (index == _managers.length) {
|
||||
return ListTile(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
title: Text('None', style: UiTypography.body1m.textSecondary),
|
||||
onTap: () => Navigator.of(context).pop(null),
|
||||
);
|
||||
}
|
||||
final dc.ListTeamMembersTeamMembers manager = _managers[index];
|
||||
return ListTile(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8),
|
||||
title: Text(manager.user.fullName ?? 'Unknown', style: UiTypography.body1m.textPrimary),
|
||||
onTap: () => Navigator.of(context).pop(manager),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (mounted) {
|
||||
if (selected == null && _managers.isEmpty) {
|
||||
// Tapped outside or selected None
|
||||
setState(() => _selectedManager = null);
|
||||
} else {
|
||||
setState(() => _selectedManager = selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildHeader() {
|
||||
return Container(
|
||||
padding: const EdgeInsets.fromLTRB(20, 24, 20, 20),
|
||||
@@ -938,7 +1113,7 @@ class OrderEditSheetState extends State<OrderEditSheet> {
|
||||
context: context,
|
||||
initialTime: TimeOfDay.now(),
|
||||
);
|
||||
if (picked != null && context.mounted) {
|
||||
if (picked != null && mounted) {
|
||||
_updatePosition(
|
||||
index,
|
||||
'start_time',
|
||||
@@ -958,7 +1133,7 @@ class OrderEditSheetState extends State<OrderEditSheet> {
|
||||
context: context,
|
||||
initialTime: TimeOfDay.now(),
|
||||
);
|
||||
if (picked != null && context.mounted) {
|
||||
if (picked != null && mounted) {
|
||||
_updatePosition(
|
||||
index,
|
||||
'end_time',
|
||||
|
||||
@@ -259,6 +259,31 @@ class _ViewOrderCardState extends State<ViewOrderCard> {
|
||||
),
|
||||
],
|
||||
),
|
||||
if (order.hubManagerName != null) ...<Widget>[
|
||||
const SizedBox(height: UiConstants.space2),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 2),
|
||||
child: Icon(
|
||||
UiIcons.user,
|
||||
size: 14,
|
||||
color: UiColors.iconSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: UiConstants.space2),
|
||||
Expanded(
|
||||
child: Text(
|
||||
order.hubManagerName!,
|
||||
style: UiTypography.footnote2r.textSecondary,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user