diff --git a/src/ui/core/zcl_abapgit_gui.clas.abap b/src/ui/core/zcl_abapgit_gui.clas.abap index 744cfef96..be0519363 100644 --- a/src/ui/core/zcl_abapgit_gui.clas.abap +++ b/src/ui/core/zcl_abapgit_gui.clas.abap @@ -29,12 +29,18 @@ CLASS zcl_abapgit_gui DEFINITION METHODS back IMPORTING !iv_to_bookmark TYPE abap_bool DEFAULT abap_false + !iv_graceful TYPE abap_bool DEFAULT abap_false RETURNING VALUE(rv_exit) TYPE abap_bool RAISING zcx_abapgit_exception . + METHODS back_graceful + RETURNING + VALUE(rv_handled) TYPE abap_bool + RAISING + zcx_abapgit_exception . METHODS on_event - FOR EVENT sapevent OF zif_abapgit_html_viewer + FOR EVENT sapevent OF zif_abapgit_html_viewer IMPORTING !action !frame @@ -65,10 +71,8 @@ CLASS zcl_abapgit_gui DEFINITION DATA mv_rollback_on_error TYPE abap_bool . DATA mi_cur_page TYPE REF TO zif_abapgit_gui_renderable . - DATA: - mt_stack TYPE STANDARD TABLE OF ty_page_stack . - DATA: - mt_event_handlers TYPE STANDARD TABLE OF REF TO zif_abapgit_gui_event_handler . + DATA mt_stack TYPE STANDARD TABLE OF ty_page_stack . + DATA mt_event_handlers TYPE STANDARD TABLE OF REF TO zif_abapgit_gui_event_handler . DATA mi_router TYPE REF TO zif_abapgit_gui_event_handler . DATA mi_asset_man TYPE REF TO zif_abapgit_gui_asset_manager . DATA mi_hotkey_ctl TYPE REF TO zif_abapgit_gui_hotkey_ctl . @@ -77,6 +81,7 @@ CLASS zcl_abapgit_gui DEFINITION DATA mo_html_parts TYPE REF TO zcl_abapgit_html_parts . DATA mi_common_log TYPE REF TO zif_abapgit_log . + METHODS cache_html IMPORTING !iv_text TYPE string @@ -105,17 +110,22 @@ CLASS zcl_abapgit_gui DEFINITION METHODS handle_error IMPORTING !ix_exception TYPE REF TO zcx_abapgit_exception . + METHODS is_page_modal + IMPORTING + !ii_page TYPE REF TO zif_abapgit_gui_renderable + RETURNING + VALUE(rv_yes) TYPE abap_bool . ENDCLASS. -CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION. +CLASS zcl_abapgit_gui IMPLEMENTATION. METHOD back. - DATA: lv_index TYPE i, - ls_stack LIKE LINE OF mt_stack. + DATA lv_index TYPE i. + DATA ls_stack LIKE LINE OF mt_stack. " If viewer is showing Internet page, then use browser navigation IF mi_html_viewer->get_url( ) CP 'http*'. @@ -130,6 +140,10 @@ CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION. RETURN. ENDIF. + IF iv_graceful = abap_true AND back_graceful( ) = abap_true. + RETURN. + ENDIF. + DO lv_index TIMES. READ TABLE mt_stack INDEX lv_index INTO ls_stack. ASSERT sy-subrc = 0. @@ -150,6 +164,29 @@ CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION. ENDMETHOD. + METHOD back_graceful. + + DATA li_handler TYPE REF TO zif_abapgit_gui_event_handler. + DATA ls_handled TYPE zif_abapgit_gui_event_handler=>ty_handling_result. + + " This code can be potentially improved + " Why send go_back to the topmost handler only ? It makes sense to notify the whole stack + " But than how to handle re-render ? render if at least one handler asks for it ? + " Probably that's the way but needs a relevant example. Postponed arch decision. + READ TABLE mt_event_handlers INTO li_handler INDEX 1. + IF sy-subrc = 0. + ls_handled = li_handler->on_event( zcl_abapgit_gui_event=>new( + iv_action = zif_abapgit_definitions=>c_action-go_back + ii_gui_services = me ) ). + IF ls_handled-state = c_event_state-re_render. " soft exit, probably popup + render( ). + rv_handled = abap_true. + ENDIF. + ENDIF. + + ENDMETHOD. + + METHOD cache_html. rv_url = zif_abapgit_gui_services~cache_asset( @@ -260,6 +297,14 @@ CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION. ENDIF. ENDLOOP. + IF is_page_modal( mi_cur_page ) = abap_true AND NOT ( + ls_handled-state = c_event_state-re_render OR + ls_handled-state = c_event_state-go_back OR + ls_handled-state = c_event_state-no_more_act ). + " Restrict new page switching from modals + ls_handled-state = c_event_state-no_more_act. + ENDIF. + CASE ls_handled-state. WHEN c_event_state-re_render. render( ). @@ -276,7 +321,7 @@ CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION. WHEN c_event_state-go_back. back( ). WHEN c_event_state-go_back_to_bookmark. - back( abap_true ). + back( iv_to_bookmark = abap_true ). WHEN c_event_state-no_more_act. " Do nothing, handling completed WHEN OTHERS. @@ -324,6 +369,21 @@ CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION. ENDMETHOD. + METHOD is_page_modal. + + DATA li_modal TYPE REF TO zif_abapgit_gui_modal. + + TRY. + IF ii_page IS BOUND. + li_modal ?= ii_page. + rv_yes = li_modal->is_modal( ). + ENDIF. + CATCH cx_sy_move_cast_error. + ENDTRY. + + ENDMETHOD. + + METHOD on_event. handle_action( @@ -347,7 +407,8 @@ CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION. CLEAR mt_event_handlers. mo_html_parts->clear( ). - IF mi_router IS BOUND. + IF mi_router IS BOUND AND is_page_modal( mi_cur_page ) = abap_false. + " No global commands in modals APPEND mi_router TO mt_event_handlers. ENDIF. diff --git a/src/ui/core/zcl_abapgit_gui_event.clas.abap b/src/ui/core/zcl_abapgit_gui_event.clas.abap index 30b8c88c3..0ce398e23 100644 --- a/src/ui/core/zcl_abapgit_gui_event.clas.abap +++ b/src/ui/core/zcl_abapgit_gui_event.clas.abap @@ -7,6 +7,14 @@ CLASS zcl_abapgit_gui_event DEFINITION INTERFACES zif_abapgit_gui_event . + CLASS-METHODS new + IMPORTING + !ii_gui_services TYPE REF TO zif_abapgit_gui_services OPTIONAL + !iv_action TYPE clike + !iv_getdata TYPE clike OPTIONAL + !it_postdata TYPE zif_abapgit_html_viewer=>ty_post_data OPTIONAL + RETURNING + VALUE(ro_instance) TYPE REF TO zcl_abapgit_gui_event. METHODS constructor IMPORTING !ii_gui_services TYPE REF TO zif_abapgit_gui_services OPTIONAL @@ -59,6 +67,16 @@ CLASS zcl_abapgit_gui_event IMPLEMENTATION. ENDMETHOD. + METHOD new. + CREATE OBJECT ro_instance + EXPORTING + ii_gui_services = ii_gui_services + iv_action = iv_action + iv_getdata = iv_getdata + it_postdata = it_postdata. + ENDMETHOD. + + METHOD zif_abapgit_gui_event~form_data. IF mo_form_data IS NOT BOUND. diff --git a/src/ui/core/zcl_abapgit_html.clas.abap b/src/ui/core/zcl_abapgit_html.clas.abap index becfb5e49..c80547286 100644 --- a/src/ui/core/zcl_abapgit_html.clas.abap +++ b/src/ui/core/zcl_abapgit_html.clas.abap @@ -10,6 +10,8 @@ CLASS zcl_abapgit_html DEFINITION CLASS-METHODS class_constructor . CLASS-METHODS create + IMPORTING + !iv_initial_chunk TYPE any OPTIONAL RETURNING VALUE(ri_instance) TYPE REF TO zif_abapgit_html. CLASS-METHODS icon @@ -107,6 +109,9 @@ CLASS zcl_abapgit_html IMPLEMENTATION. METHOD create. CREATE OBJECT ri_instance TYPE zcl_abapgit_html. + IF iv_initial_chunk IS NOT INITIAL. + ri_instance->add( iv_initial_chunk ). + ENDIF. ENDMETHOD. diff --git a/src/ui/core/zif_abapgit_gui_modal.intf.abap b/src/ui/core/zif_abapgit_gui_modal.intf.abap new file mode 100644 index 000000000..278f4e79f --- /dev/null +++ b/src/ui/core/zif_abapgit_gui_modal.intf.abap @@ -0,0 +1,8 @@ +INTERFACE zif_abapgit_gui_modal + PUBLIC . + + METHODS is_modal + RETURNING + VALUE(rv_yes) TYPE abap_bool. + +ENDINTERFACE. diff --git a/src/ui/core/zif_abapgit_gui_modal.intf.xml b/src/ui/core/zif_abapgit_gui_modal.intf.xml new file mode 100644 index 000000000..7ac598ede --- /dev/null +++ b/src/ui/core/zif_abapgit_gui_modal.intf.xml @@ -0,0 +1,15 @@ + + + + + + ZIF_ABAPGIT_GUI_MODAL + E + abapGit - GUI Renderable Component + 2 + 1 + X + + + + diff --git a/src/ui/core/zif_abapgit_gui_services.intf.abap b/src/ui/core/zif_abapgit_gui_services.intf.abap index 0f57c6663..52be01475 100644 --- a/src/ui/core/zif_abapgit_gui_services.intf.abap +++ b/src/ui/core/zif_abapgit_gui_services.intf.abap @@ -13,18 +13,17 @@ INTERFACE zif_abapgit_gui_services VALUE(rv_url) TYPE string RAISING zcx_abapgit_exception . + " Notes: + " - page_asset is supposed to be not cachable + " - add mime64 if needed (supposedly won't be needed) METHODS register_page_asset IMPORTING !iv_url TYPE string !iv_type TYPE string !iv_mime_name TYPE wwwdatatab-objid OPTIONAL !iv_inline TYPE string OPTIONAL - " Notes: - " - page_asset is supposed to be not cachable - " - add mime64 if needed (supposedly won't be needed) RAISING - zcx_abapgit_exception. - + zcx_abapgit_exception . METHODS register_event_handler IMPORTING !ii_event_handler TYPE REF TO zif_abapgit_gui_event_handler . @@ -39,7 +38,8 @@ INTERFACE zif_abapgit_gui_services VALUE(ro_parts) TYPE REF TO zcl_abapgit_html_parts . METHODS get_log IMPORTING - iv_create_new TYPE abap_bool DEFAULT abap_false + !iv_create_new TYPE abap_bool DEFAULT abap_false RETURNING - VALUE(ri_log) TYPE REF TO zif_abapgit_log. + VALUE(ri_log) TYPE REF TO zif_abapgit_log . + ENDINTERFACE. diff --git a/src/ui/lib/zcl_abapgit_gui_in_page_modal.clas.abap b/src/ui/lib/zcl_abapgit_gui_in_page_modal.clas.abap new file mode 100644 index 000000000..a949c0583 --- /dev/null +++ b/src/ui/lib/zcl_abapgit_gui_in_page_modal.clas.abap @@ -0,0 +1,82 @@ +CLASS zcl_abapgit_gui_in_page_modal DEFINITION + PUBLIC + CREATE PUBLIC. + + PUBLIC SECTION. + + INTERFACES zif_abapgit_gui_renderable. + + CLASS-METHODS create + IMPORTING + !ii_child TYPE REF TO zif_abapgit_gui_renderable + !iv_width TYPE i OPTIONAL + !iv_height TYPE i OPTIONAL + RETURNING + VALUE(ro_wrap) TYPE REF TO zcl_abapgit_gui_in_page_modal + RAISING + zcx_abapgit_exception . + METHODS constructor + IMPORTING + !ii_child TYPE REF TO zif_abapgit_gui_renderable + !iv_width TYPE i OPTIONAL + !iv_height TYPE i OPTIONAL. + + PROTECTED SECTION. + PRIVATE SECTION. + + DATA mi_child TYPE REF TO zif_abapgit_gui_renderable. + + DATA: + BEGIN OF ms_attrs, + width TYPE i, + height TYPE i, + END OF ms_attrs. + +ENDCLASS. + + + +CLASS zcl_abapgit_gui_in_page_modal IMPLEMENTATION. + + + METHOD constructor. + + ms_attrs-width = iv_width. + ms_attrs-height = iv_height. + mi_child = ii_child. + + ENDMETHOD. + + + METHOD create. + CREATE OBJECT ro_wrap + EXPORTING + ii_child = ii_child + iv_width = iv_width + iv_height = iv_height. + ENDMETHOD. + + + METHOD zif_abapgit_gui_renderable~render. + + DATA lo_style TYPE REF TO zcl_abapgit_string_buffer. + + CREATE OBJECT ri_html TYPE zcl_abapgit_html. + CREATE OBJECT lo_style. + + IF ms_attrs-width IS NOT INITIAL. + lo_style->add( |width:{ ms_attrs-width }px;| ). + ENDIF. + IF ms_attrs-height IS NOT INITIAL. + lo_style->add( |height:{ ms_attrs-height }px;| ). + ENDIF. + + ri_html->add( || ). + ri_html->add( || ). + + ENDMETHOD. +ENDCLASS. diff --git a/src/ui/lib/zcl_abapgit_gui_in_page_modal.clas.xml b/src/ui/lib/zcl_abapgit_gui_in_page_modal.clas.xml new file mode 100644 index 000000000..69834464b --- /dev/null +++ b/src/ui/lib/zcl_abapgit_gui_in_page_modal.clas.xml @@ -0,0 +1,16 @@ + + + + + + ZCL_ABAPGIT_GUI_IN_PAGE_MODAL + E + abapGit - GUI Popup + 1 + X + X + X + + + + diff --git a/src/ui/lib/zcl_abapgit_gui_picklist.clas.abap b/src/ui/lib/zcl_abapgit_gui_picklist.clas.abap new file mode 100644 index 000000000..5d1b11286 --- /dev/null +++ b/src/ui/lib/zcl_abapgit_gui_picklist.clas.abap @@ -0,0 +1,268 @@ +CLASS zcl_abapgit_gui_picklist DEFINITION + PUBLIC + INHERITING FROM zcl_abapgit_gui_component + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + + INTERFACES zif_abapgit_gui_event_handler. + INTERFACES zif_abapgit_gui_renderable. + INTERFACES zif_abapgit_gui_page_title. + + METHODS constructor + IMPORTING + !it_list TYPE STANDARD TABLE + !iv_id TYPE string OPTIONAL + !iv_in_page TYPE abap_bool DEFAULT abap_false + !iv_title TYPE string DEFAULT 'Choose from list' + !iv_attr_name TYPE abap_compname OPTIONAL + !ii_item_renderer TYPE REF TO zif_abapgit_gui_render_item OPTIONAL + RAISING + zcx_abapgit_exception. + METHODS get_result_idx + RETURNING + VALUE(rv_index) TYPE i. + METHODS get_result_item + CHANGING + !cs_selected TYPE any. + METHODS was_cancelled + RETURNING + VALUE(rv_yes) TYPE abap_bool. + METHODS is_fulfilled + RETURNING + VALUE(rv_yes) TYPE abap_bool. + METHODS id + RETURNING + VALUE(rv_id) TYPE string. + METHODS is_in_page + RETURNING + VALUE(rv_yes) TYPE abap_bool. + METHODS set_id + IMPORTING + iv_id TYPE string + RETURNING + VALUE(ro_me) TYPE REF TO zcl_abapgit_gui_picklist. + METHODS set_in_page + IMPORTING + iv_in_page TYPE abap_bool DEFAULT abap_true + RETURNING + VALUE(ro_me) TYPE REF TO zcl_abapgit_gui_picklist. + + PROTECTED SECTION. + PRIVATE SECTION. + + CONSTANTS: + BEGIN OF c_event, + back TYPE string VALUE 'back', + choose TYPE string VALUE 'choose', + END OF c_event. + + CONSTANTS c_radio_name TYPE string VALUE 'radio'. + + DATA mo_form TYPE REF TO zcl_abapgit_html_form. + DATA mo_form_data TYPE REF TO zcl_abapgit_string_map. + DATA mo_form_util TYPE REF TO zcl_abapgit_html_form_utils. + DATA mo_validation_log TYPE REF TO zcl_abapgit_string_map. + DATA mr_list TYPE REF TO data. + DATA mv_selected TYPE i. + DATA mv_cancelled TYPE abap_bool. + DATA mv_fulfilled TYPE abap_bool. + DATA mv_attr_name TYPE abap_compname. + DATA mi_item_renderer TYPE REF TO zif_abapgit_gui_render_item. + DATA mv_in_page TYPE abap_bool. + DATA mv_id TYPE string. + DATA mv_title TYPE string. + + METHODS get_form_schema + RETURNING + VALUE(ro_form) TYPE REF TO zcl_abapgit_html_form + RAISING + zcx_abapgit_exception. + METHODS return_state + RETURNING + VALUE(rv_state) TYPE zif_abapgit_gui_event_handler=>ty_handling_result-state. + +ENDCLASS. + + + +CLASS zcl_abapgit_gui_picklist IMPLEMENTATION. + + + METHOD constructor. + + FIELD-SYMBOLS TYPE STANDARD TABLE. + + super->constructor( ). + + " copy contents of table to local scope + CREATE DATA mr_list LIKE it_list. + ASSIGN mr_list->* TO . + APPEND LINES OF it_list TO . + + mv_attr_name = to_upper( iv_attr_name ). + mi_item_renderer = ii_item_renderer. + mv_in_page = iv_in_page. + mv_id = iv_id. + mv_title = iv_title. + + IF mi_item_renderer IS NOT BOUND AND mv_attr_name IS INITIAL. + zcx_abapgit_exception=>raise( 'Renderer or attr name required' ). + ENDIF. + + CREATE OBJECT mo_form_data. + CREATE OBJECT mo_validation_log. + mo_form = get_form_schema( ). + mo_form_util = zcl_abapgit_html_form_utils=>create( mo_form ). + + ENDMETHOD. + + + METHOD get_form_schema. + + FIELD-SYMBOLS TYPE ANY TABLE. + FIELD-SYMBOLS TYPE any. + FIELD-SYMBOLS TYPE any. + DATA lv_index TYPE i. + DATA lv_label TYPE string. + + ro_form = zcl_abapgit_html_form=>create( ). + + ro_form->radio( + iv_name = c_radio_name + iv_label = mv_title ). + + ASSIGN mr_list->* TO . + LOOP AT ASSIGNING . + lv_index = sy-tabix. + + IF mv_attr_name IS NOT INITIAL. + ASSIGN COMPONENT mv_attr_name OF STRUCTURE TO . + ASSERT sy-subrc = 0. + lv_label = . + ELSEIF mi_item_renderer IS BOUND. + lv_label = mi_item_renderer->render( + iv_item = + iv_index = lv_index )->render( ). + ENDIF. + + ro_form->option( + iv_label = lv_label + iv_value = |{ lv_index }| ). + + ENDLOOP. + + ro_form->command( + iv_label = 'Choose' + iv_cmd_type = zif_abapgit_html_form=>c_cmd_type-input_main + iv_action = c_event-choose + )->command( + iv_label = 'Back' + iv_action = c_event-back ). + + ENDMETHOD. + + + METHOD get_result_idx. + rv_index = mv_selected. + ENDMETHOD. + + + METHOD get_result_item. + + FIELD-SYMBOLS TYPE STANDARD TABLE. + + CLEAR cs_selected. + + IF mv_selected > 0. + ASSIGN mr_list->* TO . + READ TABLE INDEX mv_selected INTO cs_selected. + ASSERT sy-subrc = 0. + ENDIF. + + ENDMETHOD. + + + METHOD id. + rv_id = mv_id. + ENDMETHOD. + + + METHOD is_fulfilled. + rv_yes = mv_fulfilled. + ENDMETHOD. + + + METHOD is_in_page. + rv_yes = mv_in_page. + ENDMETHOD. + + + METHOD return_state. + IF mv_in_page = abap_true. + rv_state = zcl_abapgit_gui=>c_event_state-re_render. + ELSE. + rv_state = zcl_abapgit_gui=>c_event_state-go_back. + ENDIF. + ENDMETHOD. + + + METHOD set_id. + mv_id = iv_id. + ro_me = me. + ENDMETHOD. + + + METHOD set_in_page. + mv_in_page = iv_in_page. + ro_me = me. + ENDMETHOD. + + + METHOD was_cancelled. + rv_yes = mv_cancelled. + ENDMETHOD. + + + METHOD zif_abapgit_gui_event_handler~on_event. + + mo_form_data = mo_form_util->normalize( ii_event->form_data( ) ). + mo_validation_log->clear( ). + + CASE ii_event->mv_action. + WHEN c_event-back OR zif_abapgit_definitions=>c_action-go_back. + " Handle go_back as a "graceful back" - implicit cancel by F3/ESC + mv_fulfilled = abap_true. + mv_cancelled = abap_true. + rs_handled-state = return_state( ). + WHEN c_event-choose. + mv_selected = mo_form_data->get( c_radio_name ). + IF mv_selected = 0. + mo_validation_log->set( + iv_key = c_radio_name + iv_val = 'You have to select one item' ). + rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. + ELSE. + mv_fulfilled = abap_true. + rs_handled-state = return_state( ). + ENDIF. + ENDCASE. + + ENDMETHOD. + + + METHOD zif_abapgit_gui_page_title~get_page_title. + rv_title = mv_title. + ENDMETHOD. + + + METHOD zif_abapgit_gui_renderable~render. + + ri_html = zcl_abapgit_html=>create( mo_form->render( + io_values = mo_form_data + io_validation_log = mo_validation_log ) ). + register_handlers( ). + + ENDMETHOD. +ENDCLASS. diff --git a/src/ui/lib/zcl_abapgit_gui_picklist.clas.xml b/src/ui/lib/zcl_abapgit_gui_picklist.clas.xml new file mode 100644 index 000000000..3830c0365 --- /dev/null +++ b/src/ui/lib/zcl_abapgit_gui_picklist.clas.xml @@ -0,0 +1,16 @@ + + + + + + ZCL_ABAPGIT_GUI_PICKLIST + E + abapGit - Pick from list + 1 + X + X + X + + + + diff --git a/src/ui/lib/zcl_abapgit_html_popups.clas.abap b/src/ui/lib/zcl_abapgit_html_popups.clas.abap new file mode 100644 index 000000000..ed6e000a2 --- /dev/null +++ b/src/ui/lib/zcl_abapgit_html_popups.clas.abap @@ -0,0 +1,58 @@ +CLASS zcl_abapgit_html_popups DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + + CLASS-METHODS branch_list + IMPORTING + !iv_url TYPE string + !iv_default_branch TYPE string OPTIONAL + !iv_show_new_option TYPE abap_bool DEFAULT abap_false + RETURNING + VALUE(ri_popup) TYPE REF TO zif_abapgit_html_popup. + + CLASS-METHODS pull_request_list + IMPORTING + iv_url TYPE string + RETURNING + VALUE(ri_popup) TYPE REF TO zif_abapgit_html_popup. + + CLASS-METHODS tag_list + IMPORTING + iv_url TYPE string + RETURNING + VALUE(ri_popup) TYPE REF TO zif_abapgit_html_popup. + + PROTECTED SECTION. + PRIVATE SECTION. +ENDCLASS. + + + +CLASS zcl_abapgit_html_popups IMPLEMENTATION. + + + METHOD branch_list. + CREATE OBJECT ri_popup TYPE lcl_branch_popup + EXPORTING + iv_url = iv_url + iv_default_branch = iv_default_branch + iv_show_new_option = iv_show_new_option. + ENDMETHOD. + + + METHOD pull_request_list. + CREATE OBJECT ri_popup TYPE lcl_pr_popup + EXPORTING + iv_url = iv_url. + ENDMETHOD. + + + METHOD tag_list. + CREATE OBJECT ri_popup TYPE lcl_tag_popup + EXPORTING + iv_url = iv_url. + ENDMETHOD. +ENDCLASS. diff --git a/src/ui/lib/zcl_abapgit_html_popups.clas.locals_imp.abap b/src/ui/lib/zcl_abapgit_html_popups.clas.locals_imp.abap new file mode 100644 index 000000000..5a7f2e969 --- /dev/null +++ b/src/ui/lib/zcl_abapgit_html_popups.clas.locals_imp.abap @@ -0,0 +1,238 @@ +CLASS lcl_pr_popup DEFINITION FINAL. + + PUBLIC SECTION. + + INTERFACES zif_abapgit_gui_render_item. + INTERFACES zif_abapgit_html_popup. + + METHODS constructor + IMPORTING + iv_url TYPE string. + + PRIVATE SECTION. + + DATA mv_repo_url TYPE string. + + METHODS fetch_pull_request_list + RETURNING + VALUE(rt_pulls) TYPE zif_abapgit_pr_enum_provider=>ty_pull_requests + RAISING + zcx_abapgit_exception. + +ENDCLASS. + +CLASS lcl_pr_popup IMPLEMENTATION. + + METHOD constructor. + mv_repo_url = iv_url. + ENDMETHOD. + + METHOD zif_abapgit_html_popup~create_picklist. + + CREATE OBJECT ro_picklist + EXPORTING + iv_title = 'Choose Pull Request' + it_list = fetch_pull_request_list( ) + ii_item_renderer = me. + + ENDMETHOD. + + METHOD fetch_pull_request_list. + + rt_pulls = zcl_abapgit_pr_enumerator=>new( mv_repo_url )->get_pulls( ). + + IF lines( rt_pulls ) = 0. + zcx_abapgit_exception=>raise( 'No pull requests found' ). + ENDIF. + + ENDMETHOD. + + + METHOD zif_abapgit_gui_render_item~render. + + FIELD-SYMBOLS TYPE zif_abapgit_pr_enum_provider=>ty_pull_request. + + ASSIGN iv_item TO . + ASSERT sy-subrc = 0. + + ri_html = zcl_abapgit_html=>create( |{ -number } - { -title } @{ -user }| ). + + ENDMETHOD. + +ENDCLASS. + +********************************************************************** + +CLASS lcl_branch_popup DEFINITION FINAL. + + PUBLIC SECTION. + + INTERFACES zif_abapgit_gui_render_item. + INTERFACES zif_abapgit_html_popup. + + METHODS constructor + IMPORTING + !iv_url TYPE string + !iv_default_branch TYPE string OPTIONAL + !iv_show_new_option TYPE abap_bool DEFAULT abap_false. + + PRIVATE SECTION. + + DATA mv_repo_url TYPE string. + DATA mv_default_branch TYPE string. + DATA mv_show_new_option TYPE abap_bool. + + METHODS fetch_branch_list + RETURNING + VALUE(rt_branches) TYPE zif_abapgit_git_definitions=>ty_git_branch_list_tt + RAISING + zcx_abapgit_exception. + +ENDCLASS. + +CLASS lcl_branch_popup IMPLEMENTATION. + + + METHOD constructor. + mv_repo_url = iv_url. + mv_default_branch = zif_abapgit_definitions=>c_git_branch-heads_prefix && iv_default_branch. + mv_show_new_option = iv_show_new_option. + ENDMETHOD. + + METHOD zif_abapgit_html_popup~create_picklist. + + CREATE OBJECT ro_picklist + EXPORTING + iv_title = 'Choose Branch' + it_list = fetch_branch_list( ) + ii_item_renderer = me. + + ENDMETHOD. + + METHOD fetch_branch_list. + + DATA lo_branches TYPE REF TO zcl_abapgit_git_branch_list. + DATA lv_head_symref TYPE string. + + FIELD-SYMBOLS LIKE LINE OF rt_branches. + + lo_branches = zcl_abapgit_git_transport=>branches( mv_repo_url ). + rt_branches = lo_branches->get_branches_only( ). + lv_head_symref = lo_branches->get_head_symref( ). + + IF rt_branches IS INITIAL. + zcx_abapgit_exception=>raise( 'No branches are available to select' ). + ENDIF. + + " Clean up branches: HEAD duplicates, empty names + LOOP AT rt_branches ASSIGNING . + IF -name IS INITIAL. + DELETE rt_branches INDEX sy-tabix. + ELSEIF -is_head = abap_true AND lv_head_symref IS NOT INITIAL AND -name <> lv_head_symref. + DELETE rt_branches INDEX sy-tabix. + ENDIF. + ENDLOOP. + + SORT rt_branches BY is_head DESCENDING display_name ASCENDING. + + IF mv_show_new_option = abap_true. + APPEND INITIAL LINE TO rt_branches ASSIGNING . + -name = zif_abapgit_popups=>c_new_branch_label. + -display_name = zif_abapgit_popups=>c_new_branch_label. + ENDIF. + + ENDMETHOD. + + METHOD zif_abapgit_gui_render_item~render. + + DATA lv_head_marker TYPE string. + FIELD-SYMBOLS TYPE zif_abapgit_git_definitions=>ty_git_branch. + + ASSIGN iv_item TO . + ASSERT sy-subrc = 0. + + " TODO render mv_default_branch properly, needs respecting support from the picklist components + + IF -is_head = abap_true. + lv_head_marker = | ({ zif_abapgit_definitions=>c_head_name })|. + ENDIF. + + ri_html = zcl_abapgit_html=>create( |{ -display_name }{ lv_head_marker }| ). + + ENDMETHOD. + +ENDCLASS. + +********************************************************************** + +CLASS lcl_tag_popup DEFINITION FINAL. + + PUBLIC SECTION. + + INTERFACES zif_abapgit_gui_render_item. + INTERFACES zif_abapgit_html_popup. + + METHODS constructor + IMPORTING + iv_url TYPE string. + + PRIVATE SECTION. + + DATA mv_repo_url TYPE string. + + METHODS fetch_tag_list + RETURNING + VALUE(rt_tags) TYPE zif_abapgit_git_definitions=>ty_git_branch_list_tt + RAISING + zcx_abapgit_exception. + +ENDCLASS. + +CLASS lcl_tag_popup IMPLEMENTATION. + + + + METHOD constructor. + mv_repo_url = iv_url. + ENDMETHOD. + + METHOD zif_abapgit_html_popup~create_picklist. + + CREATE OBJECT ro_picklist + EXPORTING + iv_title = 'Choose Tag' + it_list = fetch_tag_list( ) + ii_item_renderer = me. + + ENDMETHOD. + + METHOD fetch_tag_list. + + DATA lo_branches TYPE REF TO zcl_abapgit_git_branch_list. + + lo_branches = zcl_abapgit_git_transport=>branches( mv_repo_url ). + rt_tags = lo_branches->get_tags_only( ). + + DELETE rt_tags WHERE name CP '*' && zif_abapgit_definitions=>c_git_branch-peel. + + IF lines( rt_tags ) = 0. + zcx_abapgit_exception=>raise( 'No tags are available to select' ). + ENDIF. + + SORT rt_tags BY display_name ASCENDING. + + ENDMETHOD. + + + METHOD zif_abapgit_gui_render_item~render. + + FIELD-SYMBOLS TYPE zif_abapgit_git_definitions=>ty_git_branch. + + ASSIGN iv_item TO . + ASSERT sy-subrc = 0. + + ri_html = zcl_abapgit_html=>create( |{ -display_name }| ). + + ENDMETHOD. + +ENDCLASS. diff --git a/src/ui/lib/zcl_abapgit_html_popups.clas.xml b/src/ui/lib/zcl_abapgit_html_popups.clas.xml new file mode 100644 index 000000000..103242309 --- /dev/null +++ b/src/ui/lib/zcl_abapgit_html_popups.clas.xml @@ -0,0 +1,16 @@ + + + + + + ZCL_ABAPGIT_HTML_POPUPS + E + abapGit - HTML Popup Library + 1 + X + X + X + + + + diff --git a/src/ui/lib/zif_abapgit_gui_render_item.intf.abap b/src/ui/lib/zif_abapgit_gui_render_item.intf.abap new file mode 100644 index 000000000..3547eff2e --- /dev/null +++ b/src/ui/lib/zif_abapgit_gui_render_item.intf.abap @@ -0,0 +1,13 @@ +INTERFACE zif_abapgit_gui_render_item + PUBLIC . + + METHODS render + IMPORTING + iv_item TYPE any + iv_index TYPE i + RETURNING + VALUE(ri_html) TYPE REF TO zif_abapgit_html + RAISING + zcx_abapgit_exception . + +ENDINTERFACE. diff --git a/src/ui/lib/zif_abapgit_gui_render_item.intf.xml b/src/ui/lib/zif_abapgit_gui_render_item.intf.xml new file mode 100644 index 000000000..29a189e8b --- /dev/null +++ b/src/ui/lib/zif_abapgit_gui_render_item.intf.xml @@ -0,0 +1,15 @@ + + + + + + ZIF_ABAPGIT_GUI_RENDER_ITEM + E + abapGit - GUI Renderable Component + 2 + 1 + X + + + + diff --git a/src/ui/lib/zif_abapgit_html_popup.intf.abap b/src/ui/lib/zif_abapgit_html_popup.intf.abap new file mode 100644 index 000000000..3f3b79c79 --- /dev/null +++ b/src/ui/lib/zif_abapgit_html_popup.intf.abap @@ -0,0 +1,10 @@ +INTERFACE zif_abapgit_html_popup + PUBLIC . + + METHODS create_picklist + RETURNING + VALUE(ro_picklist) TYPE REF TO zcl_abapgit_gui_picklist + RAISING + zcx_abapgit_exception. + +ENDINTERFACE. diff --git a/src/ui/lib/zif_abapgit_html_popup.intf.xml b/src/ui/lib/zif_abapgit_html_popup.intf.xml new file mode 100644 index 000000000..5dedaba56 --- /dev/null +++ b/src/ui/lib/zif_abapgit_html_popup.intf.xml @@ -0,0 +1,15 @@ + + + + + + ZIF_ABAPGIT_HTML_POPUP + E + abapGit - HTML Popup Interface + 2 + 1 + X + + + + diff --git a/src/ui/pages/zcl_abapgit_gui_page.clas.abap b/src/ui/pages/zcl_abapgit_gui_page.clas.abap index a9df63580..29a8a4f61 100644 --- a/src/ui/pages/zcl_abapgit_gui_page.clas.abap +++ b/src/ui/pages/zcl_abapgit_gui_page.clas.abap @@ -4,21 +4,11 @@ CLASS zcl_abapgit_gui_page DEFINITION PUBLIC ABSTRACT PUBLIC SECTION. INTERFACES: + zif_abapgit_gui_modal, zif_abapgit_gui_renderable, zif_abapgit_gui_event_handler, zif_abapgit_gui_error_handler. - METHODS: - constructor RAISING zcx_abapgit_exception. - - PROTECTED SECTION. - - CONSTANTS: - BEGIN OF c_page_layout, - centered TYPE string VALUE `centered`, - full_width TYPE string VALUE `full_width`, - END OF c_page_layout. - TYPES: BEGIN OF ty_control, page_layout TYPE string, @@ -28,8 +18,19 @@ CLASS zcl_abapgit_gui_page DEFINITION PUBLIC ABSTRACT page_title_provider TYPE REF TO zif_abapgit_gui_page_title, extra_css_url TYPE string, extra_js_url TYPE string, + show_as_modal TYPE abap_bool, END OF ty_control . + METHODS constructor RAISING zcx_abapgit_exception. + + PROTECTED SECTION. + + CONSTANTS: + BEGIN OF c_page_layout, + centered TYPE string VALUE `centered`, + full_width TYPE string VALUE `full_width`, + END OF c_page_layout. + DATA ms_control TYPE ty_control . METHODS render_content " TODO refactor, render child directly @@ -108,7 +109,7 @@ ENDCLASS. -CLASS zcl_abapgit_gui_page IMPLEMENTATION. +CLASS ZCL_ABAPGIT_GUI_PAGE IMPLEMENTATION. METHOD constructor. @@ -440,6 +441,11 @@ CLASS zcl_abapgit_gui_page IMPLEMENTATION. ENDMETHOD. + METHOD zif_abapgit_gui_modal~is_modal. + rv_yes = boolc( ms_control-show_as_modal = abap_true ). + ENDMETHOD. + + METHOD zif_abapgit_gui_renderable~render. DATA: diff --git a/src/ui/pages/zcl_abapgit_gui_page_hoc.clas.abap b/src/ui/pages/zcl_abapgit_gui_page_hoc.clas.abap index fbf761d74..9f0972963 100644 --- a/src/ui/pages/zcl_abapgit_gui_page_hoc.clas.abap +++ b/src/ui/pages/zcl_abapgit_gui_page_hoc.clas.abap @@ -2,56 +2,136 @@ CLASS zcl_abapgit_gui_page_hoc DEFINITION PUBLIC INHERITING FROM zcl_abapgit_gui_page FINAL - CREATE PRIVATE . + CREATE PRIVATE. PUBLIC SECTION. CLASS-METHODS create IMPORTING - !ii_child_component TYPE REF TO zif_abapgit_gui_renderable - !iv_page_title TYPE string OPTIONAL - !io_page_menu TYPE REF TO zcl_abapgit_html_toolbar OPTIONAL - !ii_page_menu_provider TYPE REF TO zif_abapgit_gui_menu_provider OPTIONAL + !ii_child_component TYPE REF TO zif_abapgit_gui_renderable + !iv_page_title TYPE string OPTIONAL + !iv_page_layout TYPE string DEFAULT zcl_abapgit_gui_page=>c_page_layout-centered + !io_page_menu TYPE REF TO zcl_abapgit_html_toolbar OPTIONAL + !ii_page_menu_provider TYPE REF TO zif_abapgit_gui_menu_provider OPTIONAL !ii_page_title_provider TYPE REF TO zif_abapgit_gui_page_title OPTIONAL !iv_extra_css_url TYPE string OPTIONAL !iv_extra_js_url TYPE string OPTIONAL + !iv_show_as_modal TYPE abap_bool DEFAULT abap_false RETURNING - VALUE(ri_page_wrap) TYPE REF TO zif_abapgit_gui_renderable + VALUE(ri_page_wrap) TYPE REF TO zif_abapgit_gui_renderable RAISING - zcx_abapgit_exception . + zcx_abapgit_exception. METHODS get_child RETURNING - VALUE(ri_child) TYPE REF TO zif_abapgit_gui_renderable . + VALUE(ri_child) TYPE REF TO zif_abapgit_gui_renderable. + METHODS constructor + IMPORTING + !ii_child_component TYPE REF TO zif_abapgit_gui_renderable + !is_control TYPE zcl_abapgit_gui_page=>ty_control + RAISING + zcx_abapgit_exception. PROTECTED SECTION. - METHODS render_content REDEFINITION. + + METHODS render_content + REDEFINITION. PRIVATE SECTION. DATA mi_child TYPE REF TO zif_abapgit_gui_renderable . + + METHODS detect_modal + RETURNING + VALUE(rv_is_modal) TYPE abap_bool. + + METHODS detect_menu_provider + RETURNING + VALUE(ri_ref) TYPE REF TO zif_abapgit_gui_menu_provider. + + METHODS detect_title_provider + RETURNING + VALUE(ri_ref) TYPE REF TO zif_abapgit_gui_page_title. + ENDCLASS. -CLASS ZCL_ABAPGIT_GUI_PAGE_HOC IMPLEMENTATION. +CLASS zcl_abapgit_gui_page_hoc IMPLEMENTATION. + + + METHOD constructor. + + super->constructor( ). + + mi_child = ii_child_component. + ms_control = is_control. + + IF ms_control-show_as_modal = abap_false. + ms_control-show_as_modal = detect_modal( ). + ENDIF. + + IF ms_control-page_menu_provider IS NOT BOUND. + ms_control-page_menu_provider = detect_menu_provider( ). + ENDIF. + + IF ms_control-page_title_provider IS NOT BOUND. + ms_control-page_title_provider = detect_title_provider( ). + ENDIF. + + ENDMETHOD. METHOD create. DATA lo_page TYPE REF TO zcl_abapgit_gui_page_hoc. + DATA ls_control TYPE zcl_abapgit_gui_page=>ty_control. - CREATE OBJECT lo_page. - lo_page->ms_control-page_title = iv_page_title. - lo_page->ms_control-page_menu = io_page_menu. - lo_page->ms_control-page_menu_provider = ii_page_menu_provider. - lo_page->ms_control-page_title_provider = ii_page_title_provider. - lo_page->ms_control-extra_css_url = iv_extra_css_url. - lo_page->ms_control-extra_js_url = iv_extra_js_url. - lo_page->mi_child = ii_child_component. + ls_control-page_title = iv_page_title. + ls_control-page_layout = iv_page_layout. + ls_control-page_menu = io_page_menu. + ls_control-page_menu_provider = ii_page_menu_provider. + ls_control-page_title_provider = ii_page_title_provider. + ls_control-extra_css_url = iv_extra_css_url. + ls_control-extra_js_url = iv_extra_js_url. + ls_control-show_as_modal = iv_show_as_modal. + + CREATE OBJECT lo_page + EXPORTING + ii_child_component = ii_child_component + is_control = ls_control. ri_page_wrap = lo_page. ENDMETHOD. + METHOD detect_menu_provider. + TRY. + ri_ref ?= mi_child. + CATCH cx_sy_move_cast_error. + ENDTRY. + ENDMETHOD. + + + METHOD detect_modal. + + DATA li_modal TYPE REF TO zif_abapgit_gui_modal. + + TRY. + li_modal ?= mi_child. + rv_is_modal = li_modal->is_modal( ). + CATCH cx_sy_move_cast_error. + ENDTRY. + + ENDMETHOD. + + + METHOD detect_title_provider. + TRY. + ri_ref ?= mi_child. + CATCH cx_sy_move_cast_error. + ENDTRY. + ENDMETHOD. + + METHOD get_child. ri_child = mi_child. ENDMETHOD. diff --git a/src/ui/pages/zcl_abapgit_gui_page_sett_remo.clas.abap b/src/ui/pages/zcl_abapgit_gui_page_sett_remo.clas.abap index ad7a43749..557761a11 100644 --- a/src/ui/pages/zcl_abapgit_gui_page_sett_remo.clas.abap +++ b/src/ui/pages/zcl_abapgit_gui_page_sett_remo.clas.abap @@ -68,6 +68,11 @@ CLASS zcl_abapgit_gui_page_sett_remo DEFINITION choose_pull_request TYPE string VALUE 'choose_pull_request', change_head_type TYPE string VALUE 'change_head_type', END OF c_event . + CONSTANTS: + BEGIN OF c_popup, + pull_request TYPE string VALUE 'popup_pull_request', + END OF c_popup. + DATA mo_repo TYPE REF TO zcl_abapgit_repo . DATA ms_settings_old TYPE ty_remote_settings. DATA mo_form TYPE REF TO zcl_abapgit_html_form . @@ -77,6 +82,8 @@ CLASS zcl_abapgit_gui_page_sett_remo DEFINITION DATA mv_refresh_on_back TYPE abap_bool. DATA mv_offline_switch_saved_url TYPE string. + DATA mo_popup_picklist TYPE REF TO zcl_abapgit_gui_picklist. + METHODS init IMPORTING !io_repo TYPE REF TO zcl_abapgit_repo @@ -138,13 +145,18 @@ CLASS zcl_abapgit_gui_page_sett_remo DEFINITION RAISING zcx_abapgit_exception. METHODS choose_branch - RETURNING - VALUE(rv_branch) TYPE ty_remote_settings-branch + IMPORTING + iv_is_return TYPE abap_bool DEFAULT abap_false RAISING zcx_abapgit_exception. METHODS choose_tag - RETURNING - VALUE(rv_tag) TYPE ty_remote_settings-tag + IMPORTING + iv_is_return TYPE abap_bool DEFAULT abap_false + RAISING + zcx_abapgit_exception. + METHODS choose_pr + IMPORTING + iv_is_return TYPE abap_bool DEFAULT abap_false RAISING zcx_abapgit_exception. METHODS choose_commit @@ -152,11 +164,6 @@ CLASS zcl_abapgit_gui_page_sett_remo DEFINITION VALUE(rv_commit) TYPE ty_remote_settings-commit RAISING zcx_abapgit_exception. - METHODS choose_pull_req - RETURNING - VALUE(rv_pull_request) TYPE ty_remote_settings-pull_request - RAISING - zcx_abapgit_exception. METHODS switch_online_offline RAISING @@ -179,11 +186,15 @@ CLASS zcl_abapgit_gui_page_sett_remo DEFINITION RAISING zcx_abapgit_exception. + METHODS handle_picklist_state + RAISING + zcx_abapgit_exception. + ENDCLASS. -CLASS ZCL_ABAPGIT_GUI_PAGE_SETT_REMO IMPLEMENTATION. +CLASS zcl_abapgit_gui_page_sett_remo IMPLEMENTATION. METHOD check_protection. @@ -200,27 +211,40 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_SETT_REMO IMPLEMENTATION. METHOD choose_branch. - DATA: - lv_url TYPE zif_abapgit_persistence=>ty_repo-url, - lv_branch_name TYPE zif_abapgit_persistence=>ty_repo-branch_name, - ls_branch TYPE zif_abapgit_git_definitions=>ty_git_branch. + DATA lv_url TYPE zif_abapgit_persistence=>ty_repo-url. + DATA lv_branch_name TYPE zif_abapgit_persistence=>ty_repo-branch_name. + DATA ls_branch TYPE zif_abapgit_git_definitions=>ty_git_branch. + DATA lv_popup_cancelled TYPE abap_bool. - IF mo_form_data->get( c_id-offline ) = abap_true. - RETURN. - ENDIF. + IF iv_is_return = abap_false. - lv_url = mo_form_data->get( c_id-url ). - lv_branch_name = zif_abapgit_definitions=>c_git_branch-heads_prefix && mo_form_data->get( c_id-branch ). + IF mo_form_data->get( c_id-offline ) = abap_true. + RETURN. + ENDIF. - ls_branch = zcl_abapgit_ui_factory=>get_popups( )->branch_list_popup( - iv_url = lv_url - iv_default_branch = lv_branch_name - iv_show_new_option = abap_false ). + lv_url = mo_form_data->get( c_id-url ). + lv_branch_name = mo_form_data->get( c_id-branch ). + + mo_popup_picklist = zcl_abapgit_html_popups=>branch_list( + iv_show_new_option = abap_false + iv_url = lv_url + iv_default_branch = lv_branch_name + )->create_picklist( + )->set_id( c_event-choose_branch + )->set_in_page( ). + + ELSE. + + lv_popup_cancelled = mo_popup_picklist->was_cancelled( ). + IF lv_popup_cancelled = abap_false. + mo_popup_picklist->get_result_item( CHANGING cs_selected = ls_branch ). + IF ls_branch IS NOT INITIAL. + mo_form_data->set( + iv_key = c_id-branch + iv_val = ls_branch-display_name ). + ENDIF. + ENDIF. - IF ls_branch IS NOT INITIAL. - rv_branch = ls_branch-name. - REPLACE FIRST OCCURRENCE OF zif_abapgit_definitions=>c_git_branch-heads_prefix IN rv_branch WITH space. - CONDENSE rv_branch. ENDIF. ENDMETHOD. @@ -249,30 +273,37 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_SETT_REMO IMPLEMENTATION. ENDMETHOD. - METHOD choose_pull_req. + METHOD choose_pr. - DATA: - lt_pulls TYPE zif_abapgit_pr_enum_provider=>ty_pull_requests, - ls_pull LIKE LINE OF lt_pulls, - lv_url TYPE ty_remote_settings-url. + DATA ls_pull TYPE zif_abapgit_pr_enum_provider=>ty_pull_request. + DATA lv_pull_request TYPE ty_remote_settings-pull_request. + DATA lv_url TYPE ty_remote_settings-url. + DATA lv_popup_cancelled TYPE abap_bool. - IF mo_form_data->get( c_id-offline ) = abap_true. - RETURN. - ENDIF. + IF iv_is_return = abap_false. - lv_url = mo_form_data->get( c_id-url ). + IF mo_form_data->get( c_id-offline ) = abap_true. + zcx_abapgit_exception=>raise( 'Not possible for offline repositories' ). + ENDIF. - lt_pulls = zcl_abapgit_pr_enumerator=>new( lv_url )->get_pulls( ). + lv_url = mo_form_data->get( c_id-url ). + mo_popup_picklist = zcl_abapgit_html_popups=>pull_request_list( lv_url + )->create_picklist( + )->set_id( c_event-choose_pull_request + )->set_in_page( abap_true ). - IF lines( lt_pulls ) = 0. - MESSAGE 'No pull requests found' TYPE 'S'. - RETURN. - ENDIF. + ELSE. - ls_pull = zcl_abapgit_ui_factory=>get_popups( )->choose_pr_popup( lt_pulls ). + lv_popup_cancelled = mo_popup_picklist->was_cancelled( ). + IF lv_popup_cancelled = abap_false. + mo_popup_picklist->get_result_item( CHANGING cs_selected = ls_pull ). + IF ls_pull IS NOT INITIAL. + mo_form_data->set( + iv_key = c_id-pull_request + iv_val = ls_pull-head_url && '@' && ls_pull-head_branch ). + ENDIF. + ENDIF. - IF ls_pull IS NOT INITIAL. - rv_pull_request = ls_pull-head_url && '@' && ls_pull-head_branch. ENDIF. ENDMETHOD. @@ -280,27 +311,37 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_SETT_REMO IMPLEMENTATION. METHOD choose_tag. - DATA: - lo_repo TYPE REF TO zcl_abapgit_repo_online, - ls_tag TYPE zif_abapgit_git_definitions=>ty_git_tag, - lv_url TYPE ty_remote_settings-url. + DATA ls_tag TYPE zif_abapgit_git_definitions=>ty_git_branch. + DATA lv_url TYPE ty_remote_settings-url. + DATA lv_popup_cancelled TYPE abap_bool. - IF mo_form_data->get( c_id-offline ) = abap_true. - RETURN. - ELSEIF mo_repo->is_offline( ) = abap_true. - MESSAGE 'Please save conversion to online repository before choosing a tag' TYPE 'S'. - RETURN. - ENDIF. + IF iv_is_return = abap_false. - lo_repo ?= mo_repo. - lv_url = mo_form_data->get( c_id-url ). + IF mo_form_data->get( c_id-offline ) = abap_true. + RETURN. + ELSEIF mo_repo->is_offline( ) = abap_true. + MESSAGE 'Please save conversion to online repository before choosing a tag' TYPE 'S'. + RETURN. + ENDIF. - ls_tag = zcl_abapgit_ui_factory=>get_popups( )->tag_list_popup( lv_url ). + lv_url = mo_form_data->get( c_id-url ). + mo_popup_picklist = zcl_abapgit_html_popups=>tag_list( lv_url + )->create_picklist( + )->set_id( c_event-choose_tag + )->set_in_page( ). + + ELSE. + + lv_popup_cancelled = mo_popup_picklist->was_cancelled( ). + IF lv_popup_cancelled = abap_false. + mo_popup_picklist->get_result_item( CHANGING cs_selected = ls_tag ). + IF ls_tag IS NOT INITIAL. + mo_form_data->set( + iv_key = c_id-tag + iv_val = ls_tag-display_name ). + ENDIF. + ENDIF. - IF ls_tag IS NOT INITIAL. - rv_tag = ls_tag-name. - REPLACE FIRST OCCURRENCE OF zif_abapgit_definitions=>c_git_branch-tags_prefix IN rv_tag WITH space. - CONDENSE rv_tag. ENDIF. ENDMETHOD. @@ -563,6 +604,29 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_SETT_REMO IMPLEMENTATION. ENDMETHOD. + METHOD handle_picklist_state. + + IF mo_popup_picklist IS BOUND AND + ( mo_popup_picklist->is_fulfilled( ) = abap_true OR mo_popup_picklist->is_in_page( ) = abap_false ). + " Picklist is either fullfilled OR + " it was on its own page and user went back from it via F3/ESC and the picklist had no "graceful back" handler + CASE mo_popup_picklist->id( ). + WHEN c_event-choose_pull_request. + choose_pr( iv_is_return = abap_true ). + WHEN c_event-choose_branch. + choose_branch( iv_is_return = abap_true ). + WHEN c_event-choose_tag. + choose_tag( iv_is_return = abap_true ). + WHEN OTHERS. + zcx_abapgit_exception=>raise( |Unexpected picklist id { mo_popup_picklist->id( ) }| ). + ENDCASE. + + CLEAR mo_popup_picklist. + ENDIF. + + ENDMETHOD. + + METHOD init. mo_repo = io_repo. ms_settings_old = get_remote_settings_from_repo( mo_repo ). @@ -887,13 +951,16 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_SETT_REMO IMPLEMENTATION. METHOD zif_abapgit_gui_event_handler~on_event. DATA: - lv_url TYPE ty_remote_settings-url, - lv_branch TYPE ty_remote_settings-branch, - lv_tag TYPE ty_remote_settings-tag, - lv_commit TYPE ty_remote_settings-commit, - lv_pull_request TYPE ty_remote_settings-pull_request. + lo_form_data_raw TYPE REF TO zcl_abapgit_string_map, + lv_url TYPE ty_remote_settings-url, + lv_branch TYPE ty_remote_settings-branch, + lv_tag TYPE ty_remote_settings-tag, + lv_commit TYPE ty_remote_settings-commit. - mo_form_data = mo_form_util->normalize( ii_event->form_data( ) ). + lo_form_data_raw = ii_event->form_data( ). + IF lo_form_data_raw->is_empty( ) = abap_false. " If form-related action + mo_form_data = mo_form_util->normalize( lo_form_data_raw ). + ENDIF. CASE ii_event->mv_action. WHEN zif_abapgit_definitions=>c_action-go_back. @@ -905,7 +972,6 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_SETT_REMO IMPLEMENTATION. rs_handled-state = zcl_abapgit_gui=>c_event_state-go_back_to_bookmark. WHEN c_event-choose_url. - lv_url = choose_url( ). IF lv_url IS INITIAL. @@ -922,28 +988,13 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_SETT_REMO IMPLEMENTATION. mo_validation_log->clear( ). WHEN c_event-choose_branch. - lv_branch = choose_branch( ). - - IF lv_branch IS INITIAL. - rs_handled-state = zcl_abapgit_gui=>c_event_state-no_more_act. - ELSE. - mo_form_data->set( - iv_key = c_id-branch - iv_val = lv_branch ). - rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. - ENDIF. + choose_branch( ). " Unformly handle state below WHEN c_event-choose_tag. - lv_tag = choose_tag( ). + choose_tag( ). " Unformly handle state below - IF lv_tag IS INITIAL. - rs_handled-state = zcl_abapgit_gui=>c_event_state-no_more_act. - ELSE. - mo_form_data->set( - iv_key = c_id-tag - iv_val = lv_tag ). - rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. - ENDIF. + WHEN c_event-choose_pull_request. + choose_pr( ). " Unformly handle state below WHEN c_event-choose_commit. lv_commit = choose_commit( ). @@ -957,18 +1008,6 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_SETT_REMO IMPLEMENTATION. rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. ENDIF. - WHEN c_event-choose_pull_request. - lv_pull_request = choose_pull_req( ). - - IF lv_pull_request IS INITIAL. - rs_handled-state = zcl_abapgit_gui=>c_event_state-no_more_act. - ELSE. - mo_form_data->set( - iv_key = c_id-pull_request - iv_val = lv_pull_request ). - rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. - ENDIF. - WHEN c_event-switch. switch_online_offline( ). rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. @@ -984,19 +1023,35 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_SETT_REMO IMPLEMENTATION. ENDCASE. + IF mo_popup_picklist IS BOUND. " Uniform popup state handling + " This should happen only for a new popup because + " on the first re-render main component event handling is blocked + " and not called again until the popup distruction + IF mo_popup_picklist->is_in_page( ) = abap_true. + rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. + ELSE. + rs_handled-state = zcl_abapgit_gui=>c_event_state-new_page. + rs_handled-page = zcl_abapgit_gui_page_hoc=>create( + ii_child_component = mo_popup_picklist + iv_show_as_modal = abap_true ). + ENDIF. + ENDIF. + + " If staying on form, initialize it with current settings - IF rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. - mo_form = get_form_schema( is_settings = ms_settings_old - io_form_data = mo_form_data ). - CREATE OBJECT mo_form_util - EXPORTING - io_form = mo_form. + IF rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render AND mo_popup_picklist IS NOT BOUND. + " TODO refactor: same as in constructor + mo_form = get_form_schema( + is_settings = ms_settings_old + io_form_data = mo_form_data ). + mo_form_util = zcl_abapgit_html_form_utils=>create( mo_form ). IF mo_form_data IS NOT BOUND. CREATE OBJECT mo_form_data. - initialize_form_data( io_form_data = mo_form_data - is_settings = ms_settings_old - io_form_util = mo_form_util ). + initialize_form_data( + io_form_data = mo_form_data + is_settings = ms_settings_old + io_form_util = mo_form_util ). ENDIF. ENDIF. @@ -1074,16 +1129,16 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_SETT_REMO IMPLEMENTATION. METHOD zif_abapgit_gui_renderable~render. - register_handlers( ). + handle_picklist_state( ). CREATE OBJECT ri_html TYPE zcl_abapgit_html. - ri_html->add( `
` ). + ri_html->add( `
` ). " TODO own setting frame CSS class ri_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top( - io_repo = mo_repo - iv_show_commit = abap_false - iv_interactive_branch = abap_false ) ). + io_repo = mo_repo + iv_show_commit = abap_false + iv_interactive_branch = abap_false ) ). ri_html->add( mo_form->render( io_values = mo_form_data @@ -1091,5 +1146,13 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_SETT_REMO IMPLEMENTATION. ri_html->add( `
` ). + IF mo_popup_picklist IS NOT BOUND OR mo_popup_picklist->is_in_page( ) = abap_false. + register_handlers( ). + ELSEIF mo_popup_picklist->is_in_page( ) = abap_true. + " Block usual page events if the popup is an in-page popup + ri_html->add( zcl_abapgit_gui_in_page_modal=>create( mo_popup_picklist + )->zif_abapgit_gui_renderable~render( ) ). + ENDIF. + ENDMETHOD. ENDCLASS. diff --git a/src/ui/zabapgit_css_common.w3mi.data.css b/src/ui/zabapgit_css_common.w3mi.data.css index 9cddf4473..548dfbea9 100644 --- a/src/ui/zabapgit_css_common.w3mi.data.css +++ b/src/ui/zabapgit_css_common.w3mi.data.css @@ -1502,4 +1502,52 @@ table.unit_tests { /* Warning if wrong browser control is used */ .browser-control-warning { width: 100%; -} +} + +/* MODAL POPUP */ +/* https://css-tricks.com/considerations-styling-modal/ */ + +.modal { + /* center on screen */ + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + /* size */ + max-width: 100%; + max-height: 100%; + /* infront of overlay */ + z-index: 1010; + display: block; +} + +.modal-guts { + padding: 6px 6px; + /* let it scroll */ + overflow: auto; +} + +.modal-guts .dialog { + box-shadow: 2px 2px 4px 1px rgba(0,0,0,0.3); +} + +.modal-overlay { + /* darken and prevent interactions with background */ + z-index: 1000; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.3); +} + +.modal .radio-container label { + /* hacky, improve later, get rid of !important, hook it to a named style instead */ + border-radius: 3px !important; + border: 1px solid rgba(0, 0, 0, 0.3) !important; + margin-bottom: 2px !important; +} +.modal .radio-container label:hover { + background-color: rgba(0, 0, 0, 0.1); +} diff --git a/src/utils/zcl_abapgit_string_buffer.clas.abap b/src/utils/zcl_abapgit_string_buffer.clas.abap index 49a1a4356..1124215c0 100644 --- a/src/utils/zcl_abapgit_string_buffer.clas.abap +++ b/src/utils/zcl_abapgit_string_buffer.clas.abap @@ -4,15 +4,24 @@ CLASS zcl_abapgit_string_buffer DEFINITION CREATE PUBLIC . PUBLIC SECTION. + + CLASS-METHODS new + RETURNING + VALUE(ro_me) TYPE REF TO zcl_abapgit_string_buffer. METHODS add IMPORTING - iv_str TYPE string. + !iv_str TYPE string + RETURNING + VALUE(ro_me) TYPE REF TO zcl_abapgit_string_buffer. METHODS join_and_flush RETURNING VALUE(rv_str) TYPE string. METHODS join_w_newline_and_flush RETURNING VALUE(rv_str) TYPE string. + METHODS join_w_space_and_flush + RETURNING + VALUE(rv_str) TYPE string. PROTECTED SECTION. PRIVATE SECTION. @@ -21,11 +30,12 @@ ENDCLASS. -CLASS ZCL_ABAPGIT_STRING_BUFFER IMPLEMENTATION. +CLASS zcl_abapgit_string_buffer IMPLEMENTATION. METHOD add. APPEND iv_str TO mt_buffer. + ro_me = me. ENDMETHOD. @@ -38,7 +48,20 @@ CLASS ZCL_ABAPGIT_STRING_BUFFER IMPLEMENTATION. METHOD join_w_newline_and_flush. rv_str = concat_lines_of( table = mt_buffer - sep = cl_abap_char_utilities=>newline ). + sep = cl_abap_char_utilities=>newline ). CLEAR mt_buffer. ENDMETHOD. + + + METHOD join_w_space_and_flush. + rv_str = concat_lines_of( + table = mt_buffer + sep = ` ` ). + CLEAR mt_buffer. + ENDMETHOD. + + + METHOD new. + CREATE OBJECT ro_me. + ENDMETHOD. ENDCLASS. diff --git a/src/utils/zcl_abapgit_string_buffer.clas.testclasses.abap b/src/utils/zcl_abapgit_string_buffer.clas.testclasses.abap new file mode 100644 index 000000000..dcb841295 --- /dev/null +++ b/src/utils/zcl_abapgit_string_buffer.clas.testclasses.abap @@ -0,0 +1,21 @@ +CLASS ltcl_test_strbuf DEFINITION FOR TESTING + RISK LEVEL HARMLESS + DURATION SHORT. + + PUBLIC SECTION. + + METHODS join_space FOR TESTING. + +ENDCLASS. + +CLASS ltcl_test_strbuf IMPLEMENTATION. + + METHOD join_space. + + cl_abap_unit_assert=>assert_equals( + act = zcl_abapgit_string_buffer=>new( )->add( 'a' )->add( 'b' )->join_w_space_and_flush( ) + exp = 'a b' ). + + ENDMETHOD. + +ENDCLASS. diff --git a/src/utils/zcl_abapgit_string_buffer.clas.xml b/src/utils/zcl_abapgit_string_buffer.clas.xml index 6adbc5b41..81ecaf3eb 100644 --- a/src/utils/zcl_abapgit_string_buffer.clas.xml +++ b/src/utils/zcl_abapgit_string_buffer.clas.xml @@ -10,6 +10,7 @@ X X X + X diff --git a/src/zabapgit_forms.prog.abap b/src/zabapgit_forms.prog.abap index a0a471eba..ccedc204c 100644 --- a/src/zabapgit_forms.prog.abap +++ b/src/zabapgit_forms.prog.abap @@ -78,7 +78,7 @@ FORM exit. TRY. CASE sy-ucomm. WHEN 'CBAC' OR 'CCAN'. "Back & Escape - IF zcl_abapgit_ui_factory=>get_gui( )->back( ) = abap_true. " end of stack + IF zcl_abapgit_ui_factory=>get_gui( )->back( iv_graceful = abap_true ) = abap_true. " end of stack zcl_abapgit_ui_factory=>get_gui( )->free( ). " Graceful shutdown ELSE. LEAVE TO SCREEN 1001.