diff --git a/ui/lib/modules/dashboard/create_task_dialog/create_identity/controller.dart b/ui/lib/modules/dashboard/create_task_dialog/create_identity/controller.dart new file mode 100644 index 0000000..192ec8b --- /dev/null +++ b/ui/lib/modules/dashboard/create_task_dialog/create_identity/controller.dart @@ -0,0 +1,64 @@ +import 'package:get/get.dart'; +import 'package:flutter/widgets.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; + +import '../../../../common/request.dart'; + +class CreateIdentityController extends GetxController { + RxString type = 'Qingstor'.obs; + RxString name = ''.obs; + RxString credentialProtocol = 'hamc'.obs; + RxString credentialAccessKey = ''.obs; + RxString credentialSecretKey = ''.obs; + RxString endpointProtocol = ''.obs; + RxString endpointHost = ''.obs; + RxString endpointPort = ''.obs; + + final autoValidateMode = AutovalidateMode.disabled.obs; + + void closeDialog() { + Get.back(); + Get.delete(); + } + + String get credential { + return ''' + { + protocol: "hamc", + args: [ + "$credentialAccessKey", + "$credentialSecretKey", + ], + } + '''; + } + + String get endpoint { + return ''' + { + protocol: "$endpointProtocol", + host: "$endpointHost", + port: $endpointPort, + } + '''; + } + + String get mutation { + return ''' + mutation { + createIdentity(input: { + name: "$name", + type: $type, + credential: $credential, + endpoint: $endpoint, + }) { name } + } + '''; + } + + Future createIdentity() { + return queryGraphQL(QueryOptions(document: gql(mutation))).then((result) { + return result; + }); + } +} diff --git a/ui/lib/modules/dashboard/create_task_dialog/create_identity/form.dart b/ui/lib/modules/dashboard/create_task_dialog/create_identity/form.dart new file mode 100644 index 0000000..1adf2dd --- /dev/null +++ b/ui/lib/modules/dashboard/create_task_dialog/create_identity/form.dart @@ -0,0 +1,246 @@ +import 'package:get/get.dart'; +import 'package:flutter/material.dart'; +import 'package:form_validator/form_validator.dart'; + +import '../../../../common/colors.dart'; +import '../../../../widgets/select/index.dart'; +import '../../../../widgets/select/model.dart'; +import '../../../../widgets/radio_group/index.dart'; +import '../../../../widgets/radio_group/model.dart'; + +import 'controller.dart'; + +class CreateIdentityForm extends GetView { + final GlobalKey formKey; + final Function onSubmit; + + CreateIdentityForm(this.formKey, this.onSubmit); + + @override + Widget build(BuildContext context) { + return Form( + key: formKey, + autovalidateMode: controller.autoValidateMode.value, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SelectableText( + 'Identity name'.tr, + style: TextStyle( + color: regularFontColor, + fontSize: 12, + height: 1.67, + fontWeight: FontWeight.w500, + ), + ), + SizedBox(height: 8), + TextFormField( + decoration: InputDecoration( + border: const OutlineInputBorder(), + isDense: true, + contentPadding: + EdgeInsets.symmetric(horizontal: 12, vertical: 14), + ), + maxLines: 1, + style: TextStyle(fontSize: 12), + textInputAction: TextInputAction.next, + keyboardType: TextInputType.text, + validator: ValidationBuilder() + .minLength(1, 'Please enter identity name') + .build(), + onSaved: controller.name, + ), + SizedBox(height: 22), + SelectableText( + 'Credential'.tr, + style: TextStyle( + color: regularFontColor, + fontSize: 12, + height: 1.67, + fontWeight: FontWeight.w500, + ), + ), + SizedBox(height: 4), + SelectableText( + 'Please select the protocol and fill in the corresponding value'.tr, + style: TextStyle( + color: disableFontColor, + fontSize: 10, + height: 1.5, + fontWeight: FontWeight.w400, + ), + ), + SizedBox(height: 4), + RadioGroup( + value: 'hamc', + options: [ + RadioOption( + label: 'hamc', + value: 'hamc', + ), + ], + ), + SizedBox(height: 8), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SelectableText( + 'Access key', + style: TextStyle( + color: regularFontColor, + fontSize: 12, + fontWeight: FontWeight.w400, + ), + ), + SizedBox( + width: 250, + child: TextFormField( + decoration: InputDecoration( + border: const OutlineInputBorder(), + isDense: true, + contentPadding: + EdgeInsets.symmetric(horizontal: 12, vertical: 14), + ), + maxLines: 1, + style: TextStyle(fontSize: 12), + textInputAction: TextInputAction.next, + keyboardType: TextInputType.text, + validator: ValidationBuilder() + .minLength(1, 'Please enter access key') + .build(), + onSaved: controller.credentialAccessKey, + ), + ), + ], + ), + SizedBox(height: 16), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SelectableText( + 'Secret key', + style: TextStyle( + color: regularFontColor, + fontSize: 12, + fontWeight: FontWeight.w400, + ), + ), + SizedBox( + width: 250, + child: TextFormField( + decoration: InputDecoration( + border: const OutlineInputBorder(), + isDense: true, + contentPadding: + EdgeInsets.symmetric(horizontal: 12, vertical: 14), + ), + maxLines: 1, + style: TextStyle(fontSize: 12), + textInputAction: TextInputAction.next, + keyboardType: TextInputType.text, + validator: ValidationBuilder() + .minLength(1, 'Please enter secret key') + .build(), + onSaved: controller.credentialSecretKey, + ), + ), + ], + ), + SizedBox(height: 18), + SelectableText( + 'Endpoint'.tr, + style: TextStyle( + color: regularFontColor, + fontSize: 12, + height: 1.67, + fontWeight: FontWeight.w500, + ), + ), + SizedBox(height: 4), + SelectableText( + 'Please fill in the format of :// : '.tr, + style: TextStyle( + color: disableFontColor, + fontSize: 10, + height: 1.5, + fontWeight: FontWeight.w400, + ), + ), + SizedBox(height: 8), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox( + width: 76, + child: Select( + options: [ + SelectOption(label: 'https', value: 'https'), + SelectOption(label: 'http', value: 'http'), + ], + validator: ValidationBuilder() + .minLength(1, 'Please select protocol') + .build(), + onChange: controller.endpointProtocol, + ), + ), + SelectableText( + '://', + style: TextStyle( + color: regularFontColor, + fontSize: 12, + fontWeight: FontWeight.w400, + ), + ), + SizedBox( + width: 160, + child: TextFormField( + decoration: InputDecoration( + border: const OutlineInputBorder(), + isDense: true, + contentPadding: + EdgeInsets.symmetric(horizontal: 12, vertical: 14), + ), + maxLines: 1, + style: TextStyle(fontSize: 12), + textInputAction: TextInputAction.next, + keyboardType: TextInputType.text, + validator: ValidationBuilder() + .minLength(1, 'Please enter host') + .build(), + onSaved: controller.endpointHost, + ), + ), + SelectableText( + ':', + style: TextStyle( + color: regularFontColor, + fontSize: 12, + fontWeight: FontWeight.w400, + ), + ), + SizedBox( + width: 52, + child: TextFormField( + decoration: InputDecoration( + border: const OutlineInputBorder(), + isDense: true, + contentPadding: + EdgeInsets.symmetric(horizontal: 12, vertical: 14), + ), + maxLines: 1, + style: TextStyle(fontSize: 12), + textInputAction: TextInputAction.next, + keyboardType: TextInputType.text, + validator: ValidationBuilder() + .minLength(1, 'Please enter port') + .build(), + onSaved: controller.endpointPort, + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/ui/lib/modules/dashboard/create_task_dialog/create_identity/index.dart b/ui/lib/modules/dashboard/create_task_dialog/create_identity/index.dart new file mode 100644 index 0000000..b14e6cc --- /dev/null +++ b/ui/lib/modules/dashboard/create_task_dialog/create_identity/index.dart @@ -0,0 +1,95 @@ +import 'package:get/get.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; + +import '../../../../common/colors.dart'; +import '../../../../widgets/button/index.dart'; +import '../../../../widgets/button/constants.dart'; +import '../controller.dart'; + +import 'controller.dart'; + +import 'form.dart'; + +class CreateIdentity extends StatelessWidget { + final CreateIdentityController controller = + Get.put(CreateIdentityController()); + final CreateTaskController taskController = Get.put(CreateTaskController()); + final GlobalKey formKey = GlobalKey(); + + CreateIdentity(); + + void returnCreateTask() { + taskController.isCreatingIdentity(false); + } + + void onSubmit() { + final form = formKey.currentState; + + if (!form!.validate()) { + controller.autoValidateMode(AutovalidateMode.always); + } else { + form.save(); + controller.createIdentity().then((value) { + if (taskController.step.value == 1) { + taskController.srcCredential(controller.name.value); + } else { + taskController.dstCredential(controller.name.value); + } + returnCreateTask(); + }); + } + } + + @override + Widget build(BuildContext context) { + return Container( + width: 360, + padding: EdgeInsets.only(top: 32, left: 32), + child: Column( + children: [ + GestureDetector( + onTap: () => returnCreateTask(), + child: MouseRegion( + cursor: SystemMouseCursors.click, + child: Row( + children: [ + Icon(Icons.reply, size: 16, color: regularFontColor), + SizedBox(width: 10), + Text( + 'Return to create task'.tr, + style: TextStyle( + color: regularFontColor, + fontSize: 12, + height: 1.67, + fontWeight: FontWeight.w400, + ), + ), + ], + ), + ), + ), + SizedBox(height: 24), + CreateIdentityForm(formKey, onSubmit), + SizedBox(height: 24), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Button( + child: Text("Cancel".tr), + type: ButtonType.defaults, + onPressed: () => returnCreateTask(), + ), + SizedBox(width: 12), + Button( + child: Text("Confirm".tr), + type: ButtonType.primary, + onPressed: onSubmit, + ), + ], + ), + ], + ), + ); + } +} diff --git a/ui/lib/modules/dashboard/create_task_dialog/identity_form_field/controller.dart b/ui/lib/modules/dashboard/create_task_dialog/identity_form_field/controller.dart new file mode 100644 index 0000000..900f183 --- /dev/null +++ b/ui/lib/modules/dashboard/create_task_dialog/identity_form_field/controller.dart @@ -0,0 +1,39 @@ +import 'package:get/get.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; + +import '../../../../models/identity.dart'; +import '../../../../common/request.dart'; + +class IdentityFormFieldController extends GetxController { + Rx identities = Identities.fromList([]).obs; + + final String query = ''' + query { + identities(type: Qingstor) { + name + type + credential { + protocol + args + } + endpoint { + protocol + host + port + } + } + } + '''; + + Future getIdentities() { + return queryGraphQL(QueryOptions(document: gql(query))).then((result) { + if (result.data != null) { + identities(Identities.fromList(result.data["identities"] ?? [])); + } + + return result; + }).catchError((error) { + return error; + }); + } +} diff --git a/ui/lib/modules/dashboard/create_task_dialog/identity_form_field/index.dart b/ui/lib/modules/dashboard/create_task_dialog/identity_form_field/index.dart new file mode 100644 index 0000000..5116ab6 --- /dev/null +++ b/ui/lib/modules/dashboard/create_task_dialog/identity_form_field/index.dart @@ -0,0 +1,134 @@ +import 'package:get/get.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:form_validator/form_validator.dart'; + +import '../../../../common/colors.dart'; +import '../controller.dart'; + +import 'controller.dart'; + +class IdentityFormField extends GetView { + final IdentityFormFieldController controller = + Get.put(IdentityFormFieldController()); + final CreateTaskController taskController = Get.put(CreateTaskController()); + final GlobalKey formKey = GlobalKey(); + + IdentityFormField(); + + String get getValue { + if (taskController.step.value == 1) { + return taskController.srcCredential.value; + } else { + return taskController.dstCredential.value; + } + } + + void handleChange(value) { + if (taskController.step.value == 1) { + taskController.srcCredential(value); + } else { + taskController.dstCredential(value); + } + } + + Widget createIdentity() { + return SizedBox( + width: 328, + child: OutlineButton.icon( + icon: Icon(Icons.add), + color: Colors.white, + borderSide: BorderSide( + color: primaryColor, + style: BorderStyle.solid, + ), + shape: RoundedRectangleBorder( + side: BorderSide( + color: primaryColor, + style: BorderStyle.solid, + ), + borderRadius: BorderRadius.all(Radius.circular(4))), + textColor: primaryColor, + label: Container( + height: 32, + alignment: Alignment.center, + child: Text( + 'Create identity'.tr, + style: TextStyle( + color: regularFontColor, + fontSize: 12, + fontWeight: FontWeight.w500, + ), + ), + ), + onPressed: () => taskController.isCreatingIdentity(true), + ), + ); + } + + Widget selectIdentity() { + return DropdownButtonFormField( + hint: Text('Please choose'.tr), + style: TextStyle(fontSize: 12, height: 1), + decoration: InputDecoration( + border: const OutlineInputBorder(), + isDense: true, + contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 10), + ), + value: getValue != '' ? getValue : null, + validator: + ValidationBuilder().minLength(1, 'Please select identity').build(), + onChanged: handleChange, + onSaved: handleChange, + items: [ + ...controller.identities.value.identities.map( + (identity) => DropdownMenuItem( + child: Text( + identity.name.tr, + ), + value: identity.name, + ), + ), + ], + ); + } + + @override + Widget build(BuildContext context) { + controller.getIdentities(); + + return Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + SelectableText( + 'Identity'.tr, + style: TextStyle( + color: regularFontColor, + fontSize: 12, + height: 1.67, + fontWeight: FontWeight.w500, + ), + ), + SizedBox(width: 8), + SelectableText( + 'Accessed library credential and endpoint'.tr, + style: TextStyle( + color: disableFontColor, + fontSize: 10, + fontWeight: FontWeight.w400, + ), + ), + ], + ), + SizedBox(height: 8), + Obx( + () => controller.identities.value.length() == 0 + ? createIdentity() + : selectIdentity(), + ), + ], + ); + } +} diff --git a/ui/lib/modules/dashboard/create_task_dialog/index.dart b/ui/lib/modules/dashboard/create_task_dialog/index.dart index 70212cc..17196d0 100644 --- a/ui/lib/modules/dashboard/create_task_dialog/index.dart +++ b/ui/lib/modules/dashboard/create_task_dialog/index.dart @@ -5,6 +5,7 @@ import '../../../widgets/dialog/index.dart'; import '../../../widgets/button/index.dart'; import '../../../widgets/button/constants.dart'; +import 'create_identity/index.dart'; import 'step.dart'; import 'form.dart'; @@ -21,6 +22,25 @@ class CreateTaskDialog extends StatelessWidget { controller.name(name); } + Widget getFormContent() { + if (controller.isCreatingIdentity.value) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CreateIdentity(), + ], + ); + } + + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CreateTaskStep(), + CreateTaskForm(sourceFormKey, targetFormKey, onSubmit), + ], + ); + } + bool getNextStepStatus() { return controller.isEditingName.value || controller.srcType.value.length == 0; @@ -60,17 +80,7 @@ class CreateTaskDialog extends StatelessWidget { () => CommonDialog( title: 'Create task'.tr, width: 800, - content: Container( - width: 800, - height: 548, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - CreateTaskStep(), - CreateTaskForm(sourceFormKey, targetFormKey, onSubmit), - ], - ), - ), + content: getFormContent(), actions: controller.isCreatingIdentity.value ? Container( width: 800, diff --git a/ui/lib/modules/dashboard/create_task_dialog/source_library_setting.dart b/ui/lib/modules/dashboard/create_task_dialog/source_library_setting.dart index 83a5b0b..aea1ce6 100644 --- a/ui/lib/modules/dashboard/create_task_dialog/source_library_setting.dart +++ b/ui/lib/modules/dashboard/create_task_dialog/source_library_setting.dart @@ -3,7 +3,9 @@ import 'package:flutter/material.dart'; import 'package:form_validator/form_validator.dart'; import '../../../common/colors.dart'; -import './controller.dart'; + +import 'identity_form_field/index.dart'; +import 'controller.dart'; class SourceLibrarySetting extends GetView { final GlobalKey sourceFormKey; @@ -76,62 +78,8 @@ class SourceLibrarySetting extends GetView { visible: controller.srcType.value == 'Qingstor', child: Column( children: [ - // SizedBox(height: 24), - // Row( - // crossAxisAlignment: CrossAxisAlignment.end, - // children: [ - // SelectableText( - // 'Identity'.tr, - // style: TextStyle( - // color: regularFontColor, - // fontSize: 12, - // height: 1.67, - // fontWeight: FontWeight.w500, - // ), - // ), - // SizedBox(width: 8), - // SelectableText( - // 'Accessed Library Credential And Endpoint'.tr, - // style: TextStyle( - // color: disableFontColor, - // fontSize: 10, - // fontWeight: FontWeight.w400, - // ), - // ), - // ], - // ), - // SizedBox(height: 8), - // SizedBox( - // width: 328, - // child: OutlineButton.icon( - // icon: Icon(Icons.add), - // color: Colors.white, - // borderSide: BorderSide( - // color: primaryColor, - // style: BorderStyle.solid, - // ), - // shape: RoundedRectangleBorder( - // side: BorderSide( - // color: primaryColor, - // style: BorderStyle.solid, - // ), - // borderRadius: BorderRadius.all(Radius.circular(4))), - // textColor: primaryColor, - // label: Container( - // height: 32, - // alignment: Alignment.center, - // child: Text( - // 'Create Identity'.tr, - // style: TextStyle( - // color: regularFontColor, - // fontSize: 12, - // fontWeight: FontWeight.w500, - // ), - // ), - // ), - // onPressed: () => controller.isCreatingIdentity(true), - // ), - // ), + SizedBox(height: 24), + IdentityFormField(), SizedBox(height: 24), Row( children: [ diff --git a/ui/lib/modules/dashboard/create_task_dialog/target_library_setting.dart b/ui/lib/modules/dashboard/create_task_dialog/target_library_setting.dart index c3349d5..a9661a3 100644 --- a/ui/lib/modules/dashboard/create_task_dialog/target_library_setting.dart +++ b/ui/lib/modules/dashboard/create_task_dialog/target_library_setting.dart @@ -3,7 +3,9 @@ import 'package:flutter/material.dart'; import 'package:form_validator/form_validator.dart'; import '../../../common/colors.dart'; -import './controller.dart'; + +import 'identity_form_field/index.dart'; +import 'controller.dart'; class TargetLibrarySetting extends GetView { final GlobalKey targetFormKey; @@ -76,6 +78,8 @@ class TargetLibrarySetting extends GetView { visible: controller.dstType.value == 'Qingstor', child: Column( children: [ + SizedBox(height: 24), + IdentityFormField(), SizedBox(height: 24), Row( children: [