Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions admin/lib/presentation/app/localization/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
"cancel": "Cancel",
"checkBox":"Check box",
"choice":"Choice",
"clickToSelectTheOption": "Click to select the option",
"common": "Common",
"content": "Content",
"copy": "COPY",
"create": "Create",
"customInput":"Custom input",
"customizationTextField": "Customization text field",
"date": "Date",
"defaultOptions": "Default options",
"deleteQuestion": "Delete",
"divisions": "Divisions",
"download": "DOWNLOAD",
Expand Down
1 change: 1 addition & 0 deletions admin/lib/presentation/pages/builder/builder_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ class _BuilderPageState extends State<BuilderPage> {
child: Survey(
surveyData: state.surveyData,
controller: _surveyController,
saveAnswer: false,
),
),
),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import 'package:flutter/material.dart';
import 'package:survey_admin/presentation/app/localization/app_localizations_ext.dart';
import 'package:survey_admin/presentation/widgets/customization_items/dropdown_customization_button.dart';
import 'package:survey_admin/presentation/widgets/customization_items/option.dart';
import 'package:survey_admin/presentation/widgets/customization_items/switch_customization_item.dart';
import 'package:survey_sdk/survey_sdk.dart';

class DefaultOptionsCustomizationItem extends StatelessWidget {
final List<String> options;
final List<String>? defaultOptions;
final bool isMultipleChoice;
final ValueChanged<List<String>?> onChanged;

const DefaultOptionsCustomizationItem({
required this.options,
required this.defaultOptions,
required this.isMultipleChoice,
required this.onChanged,
super.key,
});

@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SwitchCustomizationItem(
initialValue: defaultOptions != null,
title: context.localization.defaultOptions,
onChanged: (isToggled) => onChanged(
isToggled ? [options.first] : null,
),
),
if (defaultOptions != null && options.isNotEmpty) ...[
const SizedBox(height: SurveyDimensions.sizeS),
if (isMultipleChoice)
_DefaultOptionsForMultipleChoice(
defaultOptions: defaultOptions!,
options: options,
onChanged: onChanged,
)
else
_DefaultOptionsForSingleChoice(
defaultOption: defaultOptions!.first,
options: options,
onChanged: (selectedOption) => onChanged([selectedOption]),
),
],
],
);
}
}

class _DefaultOptionsForSingleChoice extends StatelessWidget {
final String defaultOption;
final List<String> options;
final ValueChanged<String> onChanged;

const _DefaultOptionsForSingleChoice({
required this.defaultOption,
required this.options,
required this.onChanged,
});

@override
Widget build(BuildContext context) {
return DropdownCustomizationButton<String>(
value: defaultOption,
withColor: true,
items: options
.map(
(option) => DropdownCustomizationItem(
value: option,
onChange: onChanged,
child: Text(
option,
style: context.theme.textTheme.bodyLarge,
),
),
)
.toList(),
);
}
}

class _DefaultOptionsForMultipleChoice extends StatelessWidget {
final List<String> defaultOptions;
final List<String> options;
final ValueChanged<List<String>?> onChanged;

const _DefaultOptionsForMultipleChoice({
required this.defaultOptions,
required this.options,
required this.onChanged,
});

@override
Widget build(BuildContext context) {
return Column(
children: [
...defaultOptions.map(
(option) => Option(
option: option,
onDelete: () {
final newOptions =
defaultOptions.where((e) => e != option).toList()..sort();

if (newOptions.isNotEmpty) {
onChanged(newOptions);
}
},
),
),
DropdownCustomizationButton<String?>(
value: null,
items: [
DropdownCustomizationItem(
value: null,
child: Text(
context.localization.clickToSelectTheOption,
style: const TextStyle(
color: SurveyColors.textHintGrey,
),
),
),
...options.where((option) => !defaultOptions.contains(option)).map(
(option) => DropdownCustomizationItem(
value: option,
onChange: (selectedOption) {
final newOptions = List.of(defaultOptions)
..add(selectedOption!)
..sort();
onChanged(newOptions);
},
child: Text(
option,
style: context.theme.textTheme.bodyLarge,
),
),
),
],
withColor: true,
),
],
);
}
}
40 changes: 40 additions & 0 deletions admin/lib/presentation/widgets/customization_items/option.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
import 'package:survey_sdk/survey_sdk.dart';

class Option extends StatelessWidget {
final String option;
final VoidCallback onDelete;

const Option({
required this.option,
required this.onDelete,
super.key,
});

@override
Widget build(BuildContext context) {
return Row(
children: [
const Icon(
Icons.fiber_manual_record,
size: SurveyDimensions.sizeS,
),
const SizedBox(width: SurveyDimensions.margin2XS),
Expanded(
child: Text(
option,
style: context.theme.textTheme.bodyLarge,
),
),
IconButton(
padding: EdgeInsets.zero,
icon: const Icon(
Icons.close,
size: SurveyDimensions.sizeM,
),
onPressed: onDelete,
),
],
);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:survey_admin/presentation/app/localization/app_localizations_ext.dart';
import 'package:survey_admin/presentation/widgets/customization_items/customization_widgets/customization_text_field.dart';
import 'package:survey_admin/presentation/widgets/customization_items/option.dart';
import 'package:survey_sdk/survey_sdk.dart';

class OptionCustomizationItem extends StatefulWidget {
Expand Down Expand Up @@ -32,7 +33,7 @@ class _OptionCustomizationItemState extends State<OptionCustomizationItem> {
}

void _onEditingComplete() {
if (_controller.text.isNotEmpty) {
if (_controller.text.isNotEmpty && !_options.contains(_controller.text)) {
setState(() => _options = [..._options, _controller.text]);
}

Expand Down Expand Up @@ -62,9 +63,9 @@ class _OptionCustomizationItemState extends State<OptionCustomizationItem> {
return Column(
children: [
..._options.map(
(option) => _Option(
(option) => Option(
option: option,
delete: () => _delete(option),
onDelete: () => _delete(option),
),
),
const SizedBox(height: SurveyDimensions.sizeS),
Expand Down Expand Up @@ -94,40 +95,3 @@ class _OptionCustomizationItemState extends State<OptionCustomizationItem> {
);
}
}

class _Option extends StatelessWidget {
final String option;
final VoidCallback delete;

const _Option({
required this.option,
required this.delete,
});

@override
Widget build(BuildContext context) {
return Row(
children: [
const Icon(
Icons.fiber_manual_record,
size: SurveyDimensions.sizeS,
),
const SizedBox(width: SurveyDimensions.margin2XS),
Expanded(
child: Text(
option,
style: context.theme.textTheme.bodyLarge,
),
),
IconButton(
padding: EdgeInsets.zero,
icon: const Icon(
Icons.close,
size: SurveyDimensions.sizeM,
),
onPressed: delete,
),
],
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:survey_admin/presentation/app/localization/app_localizations_ext
import 'package:survey_admin/presentation/widgets/base/customization_tab.dart';
import 'package:survey_admin/presentation/widgets/customization_items/color_customization_item.dart';
import 'package:survey_admin/presentation/widgets/customization_items/customization_items_container.dart';
import 'package:survey_admin/presentation/widgets/customization_items/default_options_customization_item.dart';
import 'package:survey_admin/presentation/widgets/customization_items/multiple_choice_customization_item.dart';
import 'package:survey_sdk/survey_sdk.dart';

Expand Down Expand Up @@ -33,7 +34,12 @@ class ChoiceButtonsCustomizationTab extends CustomizationTab {
MultipleChoiceCustomizationItem(
value: editable.isMultipleChoice,
onChanged: (isMultipleChoice) => onChange(
editable.copyWith(isMultipleChoice: isMultipleChoice),
editable.copyWith(
isMultipleChoice: isMultipleChoice,
selectedByDefault: editable.selectedByDefault != null
? [editable.selectedByDefault!.first]
: null,
),
),
),
],
Expand Down Expand Up @@ -65,6 +71,24 @@ class ChoiceButtonsCustomizationTab extends CustomizationTab {
),
],
),
CustomizationItemsContainer(
itemsPadding: const EdgeInsets.all(
SurveyDimensions.marginM,
),
children: [
DefaultOptionsCustomizationItem(
options: editable.options,
defaultOptions: editable.selectedByDefault,
isMultipleChoice: editable.isMultipleChoice,
onChanged: (selectedByDefault) => onChange(
editable.copyWith(
clearSelectedByDefault: selectedByDefault == null,
selectedByDefault: selectedByDefault ?? [],
),
),
),
],
),
],
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,20 @@ class ChoiceContentCustomizationTab extends CustomizationTab {
OptionCustomizationItem(
options: editable.options,
ruleValue: editable.ruleValue,
onChanged: (options, ruleValue) => onChange(
editable.copyWith(options: options, ruleValue: ruleValue),
),
onChanged: (options, ruleValue) {
final selectedByDefault = editable.selectedByDefault
?.where((option) => options.contains(option))
.toList();
onChange(
editable.copyWith(
options: options,
ruleValue: ruleValue,
selectedByDefault: selectedByDefault,
clearSelectedByDefault:
selectedByDefault == null || selectedByDefault.isEmpty,
),
);
},
),
],
),
Expand Down
Loading