diff --git a/src/ui/zcl_abapgit_gui_chunk_lib.clas.abap b/src/ui/zcl_abapgit_gui_chunk_lib.clas.abap index 59a842abf..fbad5298c 100644 --- a/src/ui/zcl_abapgit_gui_chunk_lib.clas.abap +++ b/src/ui/zcl_abapgit_gui_chunk_lib.clas.abap @@ -1,7 +1,7 @@ CLASS zcl_abapgit_gui_chunk_lib DEFINITION PUBLIC FINAL - CREATE PUBLIC . + CREATE PUBLIC. PUBLIC SECTION. @@ -109,6 +109,12 @@ CLASS zcl_abapgit_gui_chunk_lib DEFINITION !iv_act TYPE string RETURNING VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar . + CLASS-METHODS settings_repo_toolbar + IMPORTING + !iv_key TYPE zif_abapgit_persistence=>ty_repo-key + !iv_act TYPE string + RETURNING + VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar . CLASS-METHODS render_branch_name IMPORTING !iv_branch TYPE string OPTIONAL @@ -993,6 +999,26 @@ CLASS zcl_abapgit_gui_chunk_lib IMPLEMENTATION. ENDMETHOD. + METHOD settings_repo_toolbar. + + CREATE OBJECT ro_menu EXPORTING iv_id = 'toolbar-repo-settings'. + + ro_menu->add( + iv_txt = 'Repository' + iv_act = |{ zif_abapgit_definitions=>c_action-repo_settings }?key={ iv_key }| + iv_cur = boolc( iv_act = zif_abapgit_definitions=>c_action-repo_settings ) + )->add( + iv_txt = 'Local' + iv_act = |{ zif_abapgit_definitions=>c_action-repo_local_settings }?key={ iv_key }| + iv_cur = boolc( iv_act = zif_abapgit_definitions=>c_action-repo_local_settings ) + )->add( + iv_txt = 'Stats' + iv_act = |{ zif_abapgit_definitions=>c_action-repo_infos }?key={ iv_key }| + iv_cur = boolc( iv_act = zif_abapgit_definitions=>c_action-repo_infos ) ). + + ENDMETHOD. + + METHOD settings_toolbar. CREATE OBJECT ro_menu EXPORTING iv_id = 'toolbar-settings'. diff --git a/src/ui/zcl_abapgit_gui_page_sett_info.clas.abap b/src/ui/zcl_abapgit_gui_page_sett_info.clas.abap new file mode 100644 index 000000000..8e9cd12a9 --- /dev/null +++ b/src/ui/zcl_abapgit_gui_page_sett_info.clas.abap @@ -0,0 +1,449 @@ +CLASS zcl_abapgit_gui_page_sett_info DEFINITION + PUBLIC + INHERITING FROM zcl_abapgit_gui_component + FINAL + CREATE PRIVATE . + + PUBLIC SECTION. + + INTERFACES zif_abapgit_gui_event_handler . + INTERFACES zif_abapgit_gui_renderable . + + CLASS-METHODS create + IMPORTING + !io_repo TYPE REF TO zcl_abapgit_repo + RETURNING + VALUE(ri_page) TYPE REF TO zif_abapgit_gui_renderable + RAISING + zcx_abapgit_exception . + METHODS constructor + IMPORTING + !io_repo TYPE REF TO zcl_abapgit_repo + RAISING + zcx_abapgit_exception . + + PROTECTED SECTION. + PRIVATE SECTION. + + TYPES: + BEGIN OF ty_stats, + measure TYPE string, + local TYPE i, + remote TYPE i, + END OF ty_stats. + + CONSTANTS: + BEGIN OF c_id, + info TYPE string VALUE 'info', + created_by TYPE string VALUE 'created_by', + created_at TYPE string VALUE 'created_at', + deserialized_by TYPE string VALUE 'deserialized_by', + deserialized_at TYPE string VALUE 'deserialized_at', + stats TYPE string VALUE 'stats', + stats_table TYPE string VALUE 'stats_table', + END OF c_id. + CONSTANTS: + BEGIN OF c_event, + go_back TYPE string VALUE 'go-back', + save TYPE string VALUE 'save', + END OF c_event. + + DATA mo_form TYPE REF TO zcl_abapgit_html_form . + DATA mo_form_data TYPE REF TO zcl_abapgit_string_map . + + DATA mo_repo TYPE REF TO zcl_abapgit_repo. + DATA mt_stats TYPE STANDARD TABLE OF ty_stats WITH KEY measure. + DATA ms_dot TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit. + + METHODS get_form_schema + RETURNING + VALUE(ro_form) TYPE REF TO zcl_abapgit_html_form + RAISING + zcx_abapgit_exception. + METHODS read_settings + RAISING + zcx_abapgit_exception. + METHODS read_stats + RAISING + zcx_abapgit_exception. + METHODS format_user + IMPORTING + !iv_username TYPE xubname + RETURNING + VALUE(rv_user) TYPE string. + METHODS format_timestamp + IMPORTING + !iv_timestamp TYPE timestampl + RETURNING + VALUE(rv_timestamp) TYPE string. + METHODS format_size + IMPORTING + !iv_size TYPE i + RETURNING + VALUE(rv_size) TYPE string. +ENDCLASS. + + + +CLASS zcl_abapgit_gui_page_sett_info IMPLEMENTATION. + + + METHOD constructor. + + super->constructor( ). + CREATE OBJECT mo_form_data. + mo_repo = io_repo. + mo_form = get_form_schema( ). + + ENDMETHOD. + + + METHOD create. + + DATA lo_component TYPE REF TO zcl_abapgit_gui_page_sett_info. + + CREATE OBJECT lo_component + EXPORTING + io_repo = io_repo. + + ri_page = zcl_abapgit_gui_page_hoc=>create( + iv_page_title = 'Repository Stats' + io_page_menu = zcl_abapgit_gui_chunk_lib=>settings_repo_toolbar( + iv_key = io_repo->get_key( ) + iv_act = zif_abapgit_definitions=>c_action-repo_infos ) + ii_child_component = lo_component ). + + ENDMETHOD. + + + METHOD format_size. + + DATA: + lv_size TYPE p LENGTH 16 DECIMALS 2, + lv_unit TYPE string. + + IF iv_size > 1024 * 1024 * 1024. + lv_size = iv_size / 1024 / 1024 / 1024. + lv_unit = 'GB'. + ELSEIF iv_size > 1024 * 1024. + lv_size = iv_size / 1024 / 1024. + lv_unit = 'MB'. + ELSEIF iv_size > 1024. + lv_size = iv_size / 1024. + lv_unit = 'KB'. + ELSE. + lv_size = iv_size. + lv_unit = 'Bytes'. + ENDIF. + + rv_size = |{ lv_size } { lv_unit }|. + + ENDMETHOD. + + + METHOD format_timestamp. + + IF iv_timestamp IS INITIAL. + rv_timestamp = 'n/a'. + RETURN. + ENDIF. + + CALL FUNCTION 'CONVERSION_EXIT_TIMES_OUTPUT' + EXPORTING + input = iv_timestamp + IMPORTING + output = rv_timestamp. + + ENDMETHOD. + + + METHOD format_user. + + DATA: + ls_user_address TYPE addr3_val, + lv_title TYPE string. + + IF iv_username IS INITIAL. + rv_user = 'n/a'. + RETURN. + ENDIF. + + IF iv_username <> zcl_abapgit_objects_super=>c_user_unknown. + CALL FUNCTION 'SUSR_USER_ADDRESS_READ' + EXPORTING + user_name = iv_username + IMPORTING + user_address = ls_user_address + EXCEPTIONS + user_address_not_found = 1 + OTHERS = 2. + IF sy-subrc = 0. + lv_title = ls_user_address-name_text. + ENDIF. + ENDIF. + + rv_user = iv_username. + IF lv_title IS NOT INITIAL. + rv_user = |{ rv_user } ({ lv_title })|. + ENDIF. + + ENDMETHOD. + + + METHOD get_form_schema. + + ro_form = zcl_abapgit_html_form=>create( + iv_form_id = 'repo-infos-form' + iv_help_page = 'https://docs.abapgit.org/guide-repo-infos.html' ). + + ro_form->start_group( + iv_name = c_id-info + iv_label = 'Stats' + )->text( + iv_name = c_id-created_by + iv_label = 'Created By' + iv_readonly = abap_true + )->text( + iv_name = c_id-created_at + iv_label = 'Created At' + iv_readonly = abap_true + )->text( + iv_name = c_id-deserialized_by + iv_label = 'Last Deserialized By' + iv_readonly = abap_true + )->text( + iv_name = c_id-deserialized_at + iv_label = 'Last Deserialized At' + iv_readonly = abap_true + )->table( + iv_name = c_id-stats_table + iv_label = 'Statistics' + )->column( + iv_label = 'Measure' + iv_width = '50%' + iv_readonly = abap_true + )->column( + iv_label = 'Local' + iv_width = '25%' + iv_readonly = abap_true + )->column( + iv_label = 'Remote' + iv_width = '25%' + iv_readonly = abap_true + )->command( + iv_label = 'Back' + iv_action = c_event-go_back ). + + ENDMETHOD. + + + METHOD read_settings. + + DATA: + ls_repo TYPE zif_abapgit_persistence=>ty_repo, + ls_stats TYPE ty_stats, + lv_row TYPE i, + lv_int TYPE i, + lv_val TYPE string. + + " Get infos from DB + TRY. + ls_repo = zcl_abapgit_persist_factory=>get_repo( )->read( mo_repo->get_key( ) ). + CATCH zcx_abapgit_not_found. + zcx_abapgit_exception=>raise( |Repo not found, key { mo_repo->get_key( ) }| ). + ENDTRY. + + read_stats( ). + + " Infos + mo_form_data->set( + iv_key = c_id-created_by + iv_val = format_user( ls_repo-created_by ) ). + mo_form_data->set( + iv_key = c_id-created_at + iv_val = format_timestamp( ls_repo-created_at ) ). + mo_form_data->set( + iv_key = c_id-deserialized_by + iv_val = format_user( ls_repo-deserialized_by ) ). + mo_form_data->set( + iv_key = c_id-deserialized_at + iv_val = format_timestamp( ls_repo-deserialized_at ) ). + + LOOP AT mt_stats INTO ls_stats. + lv_row = sy-tabix. + DO 3 TIMES. + CASE sy-index. + WHEN 1. + lv_val = ls_stats-measure. + WHEN 2. + lv_val = ls_stats-local. + WHEN 3. + lv_val = ls_stats-remote. + ENDCASE. + + IF ls_stats-measure CS 'Size' AND sy-index BETWEEN 2 AND 3. + lv_int = lv_val. + lv_val = format_size( lv_int ). + ENDIF. + + mo_form_data->set( + iv_key = |{ c_id-stats_table }-{ lv_row }-{ sy-index }| + iv_val = lv_val ). + ENDDO. + ENDLOOP. + + mo_form_data->set( + iv_key = |{ c_id-stats_table }-{ zif_abapgit_html_form=>c_rows }| + iv_val = |{ lv_row }| ). + + ENDMETHOD. + + + METHOD read_stats. + + DATA: + lt_local TYPE zif_abapgit_definitions=>ty_files_item_tt, + lt_remote TYPE zif_abapgit_definitions=>ty_files_tt, + ls_item TYPE zif_abapgit_definitions=>ty_item, + lt_local_items TYPE STANDARD TABLE OF zif_abapgit_definitions=>ty_item WITH DEFAULT KEY, + lt_remote_items TYPE STANDARD TABLE OF zif_abapgit_definitions=>ty_item WITH DEFAULT KEY, + lt_results TYPE zif_abapgit_definitions=>ty_results_tt, + lv_ignored TYPE abap_bool, + lv_state TYPE c LENGTH 1, + ls_stats TYPE ty_stats. + + FIELD-SYMBOLS: + LIKE LINE OF lt_local, + LIKE LINE OF lt_remote, + LIKE LINE OF lt_results. + + CLEAR mt_stats. + + lt_local = mo_repo->get_files_local( ). + + ls_stats-measure = 'Number of Files'. + ls_stats-local = lines( lt_local ). + + IF mo_repo->has_remote_source( ) = abap_true. + lt_remote = mo_repo->get_files_remote( ). + ls_stats-remote = lines( lt_remote ). + ENDIF. + + APPEND ls_stats TO mt_stats. + + IF lt_remote IS NOT INITIAL. + ls_stats-measure = 'Number of Ignored Files'. + ls_stats-local = ls_stats-remote - ls_stats-local. " should be >= 0 + ls_stats-remote = 0. + APPEND ls_stats TO mt_stats. + ENDIF. + + lt_results = zcl_abapgit_file_status=>status( mo_repo ). + + DO 3 TIMES. + CLEAR ls_stats. + + CASE sy-index. + WHEN 1. + ls_stats-measure = 'Number of Modified Files'. + lv_state = zif_abapgit_definitions=>c_state-modified. + WHEN 2. + ls_stats-measure = 'Number of Added Files'. + lv_state = zif_abapgit_definitions=>c_state-added. + WHEN 3. + ls_stats-measure = 'Number of Deleted Files'. + lv_state = zif_abapgit_definitions=>c_state-deleted. + ENDCASE. + + LOOP AT lt_results ASSIGNING . + IF -lstate = lv_state. + ls_stats-local = ls_stats-local + 1. + ENDIF. + IF -rstate = lv_state. + ls_stats-remote = ls_stats-remote + 1. + ENDIF. + ENDLOOP. + + APPEND ls_stats TO mt_stats. + ENDDO. + + CLEAR ls_stats. + ls_stats-measure = 'Size of Files'. + + LOOP AT lt_local ASSIGNING . + ls_stats-local = ls_stats-local + xstrlen( -file-data ). + + COLLECT -item INTO lt_local_items. + ENDLOOP. + + IF mo_repo->has_remote_source( ) = abap_true. + LOOP AT lt_remote ASSIGNING . + ls_stats-remote = ls_stats-remote + xstrlen( -data ). + + lv_ignored = mo_repo->get_dot_abapgit( )->is_ignored( + iv_filename = -filename + iv_path = -path ). + + IF -filename IS NOT INITIAL AND lv_ignored = abap_false. + TRY. + zcl_abapgit_file_status=>identify_object( + EXPORTING + iv_filename = -filename + iv_path = -path + iv_devclass = mo_repo->get_package( ) + io_dot = mo_repo->get_dot_abapgit( ) + IMPORTING + es_item = ls_item ). + + COLLECT ls_item INTO lt_remote_items. + CATCH zcx_abapgit_exception ##NO_HANDLER. + ENDTRY. + ENDIF. + + ENDLOOP. + ENDIF. + + APPEND ls_stats TO mt_stats. + + CLEAR ls_stats. + ls_stats-measure = 'Number of Objects'. + + DELETE lt_local_items WHERE obj_type IS INITIAL OR obj_name IS INITIAL. + ls_stats-local = lines( lt_local_items ). + + DELETE lt_remote_items WHERE obj_type IS INITIAL OR obj_name IS INITIAL. + ls_stats-remote = lines( lt_remote_items ). + + APPEND ls_stats TO mt_stats. + + ENDMETHOD. + + + METHOD zif_abapgit_gui_event_handler~on_event. + + IF ii_event->mv_action = c_event-go_back. + rs_handled-state = zcl_abapgit_gui=>c_event_state-go_back_to_bookmark. + ENDIF. + + ENDMETHOD. + + + METHOD zif_abapgit_gui_renderable~render. + + gui_services( )->register_event_handler( me ). + + read_settings( ). + + CREATE OBJECT ri_html TYPE zcl_abapgit_html. + + ri_html->add( `
` ). + ri_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top( + io_repo = mo_repo + iv_show_commit = abap_false + iv_interactive_branch = abap_true ) ). + ri_html->add( `
` ). + + ri_html->add( mo_form->render( mo_form_data ) ). + + ENDMETHOD. +ENDCLASS. diff --git a/src/ui/zcl_abapgit_gui_page_sett_info.clas.xml b/src/ui/zcl_abapgit_gui_page_sett_info.clas.xml new file mode 100644 index 000000000..e5679771a --- /dev/null +++ b/src/ui/zcl_abapgit_gui_page_sett_info.clas.xml @@ -0,0 +1,16 @@ + + + + + + ZCL_ABAPGIT_GUI_PAGE_SETT_INFO + E + abapGit - Repository Infos + 1 + X + X + X + + + + diff --git a/src/ui/zcl_abapgit_gui_page_sett_locl.clas.abap b/src/ui/zcl_abapgit_gui_page_sett_locl.clas.abap new file mode 100644 index 000000000..fcca32fc5 --- /dev/null +++ b/src/ui/zcl_abapgit_gui_page_sett_locl.clas.abap @@ -0,0 +1,292 @@ +CLASS zcl_abapgit_gui_page_sett_locl DEFINITION + PUBLIC + INHERITING FROM zcl_abapgit_gui_component + FINAL + CREATE PRIVATE . + + PUBLIC SECTION. + + INTERFACES zif_abapgit_gui_event_handler . + INTERFACES zif_abapgit_gui_renderable . + + CLASS-METHODS create + IMPORTING + !io_repo TYPE REF TO zcl_abapgit_repo + RETURNING + VALUE(ri_page) TYPE REF TO zif_abapgit_gui_renderable + RAISING + zcx_abapgit_exception . + METHODS constructor + IMPORTING + !io_repo TYPE REF TO zcl_abapgit_repo + RAISING + zcx_abapgit_exception . + + PROTECTED SECTION. + PRIVATE SECTION. + + CONSTANTS: + BEGIN OF c_id, + local TYPE string VALUE 'local', + display_name TYPE string VALUE 'display_name', + ignore_subpackages TYPE string VALUE 'ignore_subpackages', + write_protected TYPE string VALUE 'write_protected', + only_local_objects TYPE string VALUE 'only_local_objects', + serialize_master_lang_only TYPE string VALUE 'serialize_master_lang_only', + checks TYPE string VALUE 'checks', + code_inspector_check_variant TYPE string VALUE 'code_inspector_check_variant', + block_commit TYPE string VALUE 'block_commit', + END OF c_id . + CONSTANTS: + BEGIN OF c_event, + go_back TYPE string VALUE 'go_back', + save TYPE string VALUE 'save', + END OF c_event . + + 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 mo_repo TYPE REF TO zcl_abapgit_repo . + DATA ms_settings TYPE zif_abapgit_persistence=>ty_repo-local_settings . + + METHODS validate_form + IMPORTING + !io_form_data TYPE REF TO zcl_abapgit_string_map + RETURNING + VALUE(ro_validation_log) TYPE REF TO zcl_abapgit_string_map + RAISING + zcx_abapgit_exception . + METHODS get_form_schema + RETURNING + VALUE(ro_form) TYPE REF TO zcl_abapgit_html_form + RAISING + zcx_abapgit_exception . + METHODS read_settings + RAISING + zcx_abapgit_exception . + METHODS save_settings + RAISING + zcx_abapgit_exception . +ENDCLASS. + + + +CLASS zcl_abapgit_gui_page_sett_locl IMPLEMENTATION. + + + METHOD constructor. + + super->constructor( ). + CREATE OBJECT mo_validation_log. + CREATE OBJECT mo_form_data. + mo_repo = io_repo. + mo_form = get_form_schema( ). + mo_form_util = zcl_abapgit_html_form_utils=>create( mo_form ). + + read_settings( ). + + ENDMETHOD. + + + METHOD create. + + DATA lo_component TYPE REF TO zcl_abapgit_gui_page_sett_locl. + + CREATE OBJECT lo_component + EXPORTING + io_repo = io_repo. + + ri_page = zcl_abapgit_gui_page_hoc=>create( + iv_page_title = 'Local Settings & Checks' + io_page_menu = zcl_abapgit_gui_chunk_lib=>settings_repo_toolbar( + iv_key = io_repo->get_key( ) + iv_act = zif_abapgit_definitions=>c_action-repo_local_settings ) + ii_child_component = lo_component ). + + ENDMETHOD. + + + METHOD get_form_schema. + + ro_form = zcl_abapgit_html_form=>create( + iv_form_id = 'repo-local-settings-form' + iv_help_page = 'https://docs.abapgit.org/guide-repo-local.html' ). + + ro_form->start_group( + iv_name = c_id-local + iv_label = 'Local Settings' + iv_hint = 'Settings valid for this system only' + )->text( + iv_name = c_id-display_name + iv_label = 'Display Name' + iv_hint = 'Name to show instead of original repo name (optional)' + )->checkbox( + iv_name = c_id-write_protected + iv_label = 'Write Protected' + iv_hint = 'Lock repository against changes from remote (pull)' + )->checkbox( + iv_name = c_id-ignore_subpackages + iv_label = 'Ignore Subpackages' + iv_hint = 'Syncronize root package only' + )->checkbox( + iv_name = c_id-only_local_objects + iv_label = 'Only Local Objects' + iv_hint = 'Ignore objects imported from other systems; serialize only objects created in this system' + )->checkbox( + iv_name = c_id-serialize_master_lang_only + iv_label = 'Only Serialize Main Language' + iv_hint = 'Ignore translations; serialize only main language of repository' + )->start_group( + iv_name = c_id-checks + iv_label = 'Local Checks' + iv_hint = 'Code Inspector check performed to run from menu and before commit' + )->text( + iv_name = c_id-code_inspector_check_variant + iv_label = 'Code Inspector Check Variant' + iv_hint = 'Global check variant for Code Inspector or ABAP Test Cockpit' + )->checkbox( + iv_name = c_id-block_commit + iv_label = 'Block Commit If Code Inspection Has Errors' + iv_hint = 'Prevent staging if errors of priority 1 or 2 were found during check' + )->command( + iv_label = 'Save Settings' + iv_cmd_type = zif_abapgit_html_form=>c_cmd_type-input_main + iv_action = c_event-save + )->command( + iv_label = 'Back' + iv_action = c_event-go_back ). + + ENDMETHOD. + + + METHOD read_settings. + + " Get settings from DB + ms_settings = mo_repo->get_local_settings( ). + + " Local Settings + mo_form_data->set( + iv_key = c_id-display_name + iv_val = ms_settings-display_name ). + mo_form_data->set( + iv_key = c_id-ignore_subpackages + iv_val = boolc( ms_settings-ignore_subpackages = abap_true ) ). + mo_form_data->set( + iv_key = c_id-serialize_master_lang_only + iv_val = boolc( ms_settings-serialize_master_lang_only = abap_true ) ). + mo_form_data->set( + iv_key = c_id-write_protected + iv_val = boolc( ms_settings-write_protected = abap_true ) ). + mo_form_data->set( + iv_key = c_id-only_local_objects + iv_val = boolc( ms_settings-only_local_objects = abap_true ) ). + mo_form_data->set( + iv_key = c_id-code_inspector_check_variant + iv_val = |{ ms_settings-code_inspector_check_variant }| ). + mo_form_data->set( + iv_key = c_id-block_commit + iv_val = boolc( ms_settings-block_commit = abap_true ) ). + + " Set for is_dirty check + mo_form_util->set_data( mo_form_data ). + + ENDMETHOD. + + + METHOD save_settings. + + ms_settings-display_name = mo_form_data->get( c_id-display_name ). + ms_settings-ignore_subpackages = mo_form_data->get( c_id-ignore_subpackages ). + ms_settings-serialize_master_lang_only = mo_form_data->get( c_id-serialize_master_lang_only ). + ms_settings-write_protected = mo_form_data->get( c_id-write_protected ). + ms_settings-only_local_objects = mo_form_data->get( c_id-only_local_objects ). + ms_settings-code_inspector_check_variant = mo_form_data->get( c_id-code_inspector_check_variant ). + ms_settings-block_commit = mo_form_data->get( c_id-block_commit ). + + mo_repo->set_local_settings( ms_settings ). + + COMMIT WORK AND WAIT. + + MESSAGE 'Settings succesfully saved' TYPE 'S'. + + read_settings( ). + + ENDMETHOD. + + + METHOD validate_form. + + DATA: + lx_error TYPE REF TO zcx_abapgit_exception, + lv_check_variant TYPE sci_chkv. + + ro_validation_log = mo_form_util->validate( io_form_data ). + + lv_check_variant = to_upper( io_form_data->get( c_id-code_inspector_check_variant ) ). + IF lv_check_variant IS NOT INITIAL. + TRY. + zcl_abapgit_code_inspector=>validate_check_variant( lv_check_variant ). + CATCH zcx_abapgit_exception INTO lx_error. + ro_validation_log->set( + iv_key = c_id-code_inspector_check_variant + iv_val = lx_error->get_text( ) ). + ENDTRY. + ENDIF. + + IF io_form_data->get( c_id-block_commit ) = abap_true AND lv_check_variant IS INITIAL. + ro_validation_log->set( + iv_key = c_id-block_commit + iv_val = |If block commit is active, a check variant has to be maintained| ). + ENDIF. + + ENDMETHOD. + + + METHOD zif_abapgit_gui_event_handler~on_event. + + mo_form_data = mo_form_util->normalize( ii_event->form_data( ) ). + + CASE ii_event->mv_action. + WHEN c_event-go_back. + rs_handled-state = mo_form_util->exit( mo_form_data ). + + WHEN c_event-save. + " Validate form entries before saving + mo_validation_log = validate_form( mo_form_data ). + + IF mo_validation_log->is_empty( ) = abap_true. + save_settings( ). + ENDIF. + + rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. + + ENDCASE. + + ENDMETHOD. + + + METHOD zif_abapgit_gui_renderable~render. + + gui_services( )->register_event_handler( me ). + + IF mo_form_util->is_empty( mo_form_data ) = abap_true. + read_settings( ). + ENDIF. + + CREATE OBJECT ri_html TYPE zcl_abapgit_html. + + ri_html->add( `
` ). + ri_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top( + io_repo = mo_repo + iv_show_commit = abap_false + iv_interactive_branch = abap_true ) ). + ri_html->add( `
` ). + + ri_html->add( mo_form->render( + io_values = mo_form_data + io_validation_log = mo_validation_log ) ). + + ENDMETHOD. +ENDCLASS. diff --git a/src/ui/zcl_abapgit_gui_page_sett_locl.clas.xml b/src/ui/zcl_abapgit_gui_page_sett_locl.clas.xml new file mode 100644 index 000000000..ea4f80d87 --- /dev/null +++ b/src/ui/zcl_abapgit_gui_page_sett_locl.clas.xml @@ -0,0 +1,16 @@ + + + + + + ZCL_ABAPGIT_GUI_PAGE_SETT_LOCL + E + abapGit - Local Settings for Repository + 1 + X + X + X + + + + diff --git a/src/ui/zcl_abapgit_gui_page_sett_repo.clas.abap b/src/ui/zcl_abapgit_gui_page_sett_repo.clas.abap new file mode 100644 index 000000000..d7177b62a --- /dev/null +++ b/src/ui/zcl_abapgit_gui_page_sett_repo.clas.abap @@ -0,0 +1,395 @@ +CLASS zcl_abapgit_gui_page_sett_repo DEFINITION + PUBLIC + INHERITING FROM zcl_abapgit_gui_component + FINAL + CREATE PRIVATE . + + PUBLIC SECTION. + + INTERFACES zif_abapgit_gui_event_handler . + INTERFACES zif_abapgit_gui_renderable . + + CLASS-METHODS create + IMPORTING + !io_repo TYPE REF TO zcl_abapgit_repo + RETURNING + VALUE(ri_page) TYPE REF TO zif_abapgit_gui_renderable + RAISING + zcx_abapgit_exception . + METHODS constructor + IMPORTING + !io_repo TYPE REF TO zcl_abapgit_repo + RAISING + zcx_abapgit_exception . + + PROTECTED SECTION. + PRIVATE SECTION. + + CONSTANTS: + BEGIN OF c_id, + dot TYPE string VALUE 'dot', + master_language TYPE string VALUE 'master_language', + starting_folder TYPE string VALUE 'starting_folder', + folder_logic TYPE string VALUE 'folder_logic', + ignore TYPE string VALUE 'ignore', + requirements TYPE string VALUE 'requirements', + END OF c_id . + CONSTANTS: + BEGIN OF c_event, + go_back TYPE string VALUE 'go_back', + save TYPE string VALUE 'save', + END OF c_event . + CONSTANTS c_empty_rows TYPE i VALUE 2 ##NO_TEXT. + + 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 mo_repo TYPE REF TO zcl_abapgit_repo . + DATA mv_requirements_count TYPE i . + + METHODS validate_form + IMPORTING + !io_form_data TYPE REF TO zcl_abapgit_string_map + RETURNING + VALUE(ro_validation_log) TYPE REF TO zcl_abapgit_string_map + RAISING + zcx_abapgit_exception . + METHODS get_form_schema + RETURNING + VALUE(ro_form) TYPE REF TO zcl_abapgit_html_form + RAISING + zcx_abapgit_exception . + METHODS read_settings + RAISING + zcx_abapgit_exception . + METHODS save_settings + RAISING + zcx_abapgit_exception . +ENDCLASS. + + + +CLASS zcl_abapgit_gui_page_sett_repo IMPLEMENTATION. + + + METHOD constructor. + + super->constructor( ). + CREATE OBJECT mo_validation_log. + CREATE OBJECT mo_form_data. + mo_repo = io_repo. + mo_form = get_form_schema( ). + mo_form_util = zcl_abapgit_html_form_utils=>create( mo_form ). + + read_settings( ). + + ENDMETHOD. + + + METHOD create. + + DATA lo_component TYPE REF TO zcl_abapgit_gui_page_sett_repo. + + CREATE OBJECT lo_component + EXPORTING + io_repo = io_repo. + + ri_page = zcl_abapgit_gui_page_hoc=>create( + iv_page_title = 'Repository Settings' + io_page_menu = zcl_abapgit_gui_chunk_lib=>settings_repo_toolbar( + iv_key = io_repo->get_key( ) + iv_act = zif_abapgit_definitions=>c_action-repo_settings ) + ii_child_component = lo_component ). + + ENDMETHOD. + + + METHOD get_form_schema. + + ro_form = zcl_abapgit_html_form=>create( + iv_form_id = 'repo-settings-form' + iv_help_page = 'https://docs.abapgit.org/ref-dot-abapgit.html' ). + + ro_form->start_group( + iv_name = c_id-dot + iv_label = 'Repository Settings (.abapgit.xml)' + iv_hint = 'Settings stored in root folder in .abapgit.xml file' + )->text( + iv_name = c_id-master_language + iv_label = 'Main Language' + iv_hint = 'Main language of repository (cannot be changed)' + iv_readonly = abap_true + )->radio( + iv_name = c_id-folder_logic + iv_default_value = zif_abapgit_dot_abapgit=>c_folder_logic-prefix + iv_label = 'Folder Logic' + iv_hint = 'Define how package folders are named in repository' + )->option( + iv_label = 'Prefix' + iv_value = zif_abapgit_dot_abapgit=>c_folder_logic-prefix + )->option( + iv_label = 'Full' + iv_value = zif_abapgit_dot_abapgit=>c_folder_logic-full + )->text( + iv_name = c_id-starting_folder + iv_label = 'Starting Folder' + iv_hint = 'Root folder that defines where serialization starts' + )->textarea( + iv_name = c_id-ignore + iv_label = 'Ignore Files' + iv_hint = 'List of files in starting folder that shall not be serialized' + )->table( + iv_name = c_id-requirements + iv_label = 'Requirements' + iv_hint = 'List of software components with minimum release and patch' + )->column( + iv_label = 'Software Component' + iv_width = '40%' + )->column( + iv_label = 'Minimum Release' + iv_width = '30%' + )->column( + iv_label = 'Minimum Patch' + iv_width = '30%' + )->command( + iv_label = 'Save Settings' + iv_cmd_type = zif_abapgit_html_form=>c_cmd_type-input_main + iv_action = c_event-save + )->command( + iv_label = 'Back' + iv_action = c_event-go_back ). + + ENDMETHOD. + + + METHOD read_settings. + + DATA: + ls_dot TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit, + lv_language TYPE t002t-sptxt, + lv_ignore TYPE string, + ls_requirements LIKE LINE OF ls_dot-requirements, + lv_row TYPE i, + lv_val TYPE string. + + FIELD-SYMBOLS: + TYPE string. + + " Get settings from DB + ls_dot = mo_repo->get_dot_abapgit( )->get_data( ). + + " Repository Settings + SELECT SINGLE sptxt INTO lv_language FROM t002t + WHERE spras = sy-langu AND sprsl = ls_dot-master_language. + IF sy-subrc <> 0. + lv_language = 'Unknown language; Check your .abapgit.xml file'. + ENDIF. + + mo_form_data->set( + iv_key = c_id-master_language + iv_val = |{ ls_dot-master_language } ({ lv_language })| ). + mo_form_data->set( + iv_key = c_id-folder_logic + iv_val = ls_dot-folder_logic ). + mo_form_data->set( + iv_key = c_id-starting_folder + iv_val = ls_dot-starting_folder ). + + LOOP AT ls_dot-ignore ASSIGNING . + lv_ignore = lv_ignore && && zif_abapgit_definitions=>c_newline. + ENDLOOP. + IF sy-subrc <> 0. + lv_ignore = zif_abapgit_definitions=>c_newline. + ENDIF. + + mo_form_data->set( + iv_key = c_id-ignore + iv_val = lv_ignore ). + + LOOP AT ls_dot-requirements INTO ls_requirements. + lv_row = sy-tabix. + DO 3 TIMES. + CASE sy-index. + WHEN 1. + lv_val = ls_requirements-component. + WHEN 2. + lv_val = ls_requirements-min_release. + WHEN 3. + lv_val = ls_requirements-min_patch. + ENDCASE. + mo_form_data->set( + iv_key = |{ c_id-requirements }-{ lv_row }-{ sy-index }| + iv_val = lv_val ). + ENDDO. + ENDLOOP. + + DO c_empty_rows TIMES. + lv_row = sy-index. + DO 3 TIMES. + mo_form_data->set( + iv_key = |{ c_id-requirements }-{ lv_row }-{ sy-index }| + iv_val = '' ). + ENDDO. + ENDDO. + + mv_requirements_count = lv_row. + + mo_form_data->set( + iv_key = |{ c_id-requirements }-{ zif_abapgit_html_form=>c_rows }| + iv_val = |{ mv_requirements_count }| ). + + " Set for is_dirty check + mo_form_util->set_data( mo_form_data ). + + ENDMETHOD. + + + METHOD save_settings. + + DATA: + lo_dot TYPE REF TO zcl_abapgit_dot_abapgit, + lv_ignore TYPE string, + lt_ignore TYPE STANDARD TABLE OF string WITH DEFAULT KEY, + lv_rows TYPE i, + ls_requirements TYPE zif_abapgit_dot_abapgit=>ty_requirement, + lt_requirements TYPE zif_abapgit_dot_abapgit=>ty_requirement_tt. + + lo_dot = mo_repo->get_dot_abapgit( ). + + lo_dot->set_folder_logic( mo_form_data->get( c_id-folder_logic ) ). + lo_dot->set_starting_folder( mo_form_data->get( c_id-starting_folder ) ). + + " Remove all ignores + lt_ignore = lo_dot->get_data( )-ignore. + LOOP AT lt_ignore INTO lv_ignore. + lo_dot->remove_ignore( iv_path = '' + iv_filename = lv_ignore ). + ENDLOOP. + + " Add newly entered ignores + lt_ignore = zcl_abapgit_convert=>split_string( mo_form_data->get( c_id-ignore ) ). + LOOP AT lt_ignore INTO lv_ignore WHERE table_line IS NOT INITIAL. + lo_dot->add_ignore( iv_path = '' + iv_filename = lv_ignore ). + ENDLOOP. + + " Requirements + DO mv_requirements_count TIMES. + ls_requirements-component = to_upper( mo_form_data->get( |{ c_id-requirements }-{ sy-index }-1| ) ). + ls_requirements-min_release = mo_form_data->get( |{ c_id-requirements }-{ sy-index }-2| ). + ls_requirements-min_patch = mo_form_data->get( |{ c_id-requirements }-{ sy-index }-3| ). + APPEND ls_requirements TO lt_requirements. + ENDDO. + + SORT lt_requirements BY component min_release min_patch. + DELETE lt_requirements WHERE component IS INITIAL. + DELETE ADJACENT DUPLICATES FROM lt_requirements COMPARING ALL FIELDS. + + lo_dot->set_requirements( lt_requirements ). + + mo_repo->set_dot_abapgit( lo_dot ). + mo_repo->refresh( ). + + COMMIT WORK AND WAIT. + + MESSAGE 'Settings succesfully saved' TYPE 'S'. + + read_settings( ). + + ENDMETHOD. + + + METHOD validate_form. + + DATA: + lv_folder TYPE string, + lv_len TYPE i, + lv_component TYPE zif_abapgit_dot_abapgit=>ty_requirement-component, + lv_min_release TYPE zif_abapgit_dot_abapgit=>ty_requirement-min_release, + lv_min_patch TYPE zif_abapgit_dot_abapgit=>ty_requirement-min_patch. + + ro_validation_log = mo_form_util->validate( io_form_data ). + + lv_folder = io_form_data->get( c_id-starting_folder ). + lv_len = strlen( lv_folder ) - 1. + IF lv_len > 0 AND lv_folder(1) <> '/'. + ro_validation_log->set( + iv_key = c_id-starting_folder + iv_val = |The folder must begin with /| ). + ELSEIF lv_len > 0 AND lv_folder+lv_len(1) <> '/'. + ro_validation_log->set( + iv_key = c_id-starting_folder + iv_val = |The folder must end with /| ). + ELSEIF lv_folder CA '\'. + ro_validation_log->set( + iv_key = c_id-starting_folder + iv_val = |Use / instead of \\| ). + ENDIF. + + DO mv_requirements_count TIMES. + lv_component = mo_form_data->get( |{ c_id-requirements }-{ sy-index }-1| ). + lv_min_release = mo_form_data->get( |{ c_id-requirements }-{ sy-index }-2| ). + lv_min_patch = mo_form_data->get( |{ c_id-requirements }-{ sy-index }-3| ). + + IF lv_component IS INITIAL AND ( lv_min_release IS NOT INITIAL OR lv_min_patch IS NOT INITIAL ). + ro_validation_log->set( + iv_key = c_id-requirements + iv_val = |If you enter a release or patch, you must also enter a software component| ). + ELSEIF lv_component IS NOT INITIAL AND lv_min_release IS INITIAL. + ro_validation_log->set( + iv_key = c_id-requirements + iv_val = |If you enter a software component, you must also enter a minumum release| ). + ENDIF. + ENDDO. + + ENDMETHOD. + + + METHOD zif_abapgit_gui_event_handler~on_event. + + mo_form_data = mo_form_util->normalize( ii_event->form_data( ) ). + + CASE ii_event->mv_action. + WHEN c_event-go_back. + rs_handled-state = mo_form_util->exit( mo_form_data ). + + WHEN c_event-save. + " Validate all form entries + mo_validation_log = validate_form( mo_form_data ). + + IF mo_validation_log->is_empty( ) = abap_true. + save_settings( ). + ENDIF. + + rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. + + ENDCASE. + + ENDMETHOD. + + + METHOD zif_abapgit_gui_renderable~render. + + gui_services( )->register_event_handler( me ). + + IF mo_form_util->is_empty( mo_form_data ) = abap_true. + read_settings( ). + ENDIF. + + CREATE OBJECT ri_html TYPE zcl_abapgit_html. + + ri_html->add( `
` ). + ri_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top( + io_repo = mo_repo + iv_show_commit = abap_false + iv_interactive_branch = abap_true ) ). + ri_html->add( `
` ). + + ri_html->add( mo_form->render( + io_values = mo_form_data + io_validation_log = mo_validation_log ) ). + + ENDMETHOD. +ENDCLASS. diff --git a/src/ui/zcl_abapgit_gui_page_sett_repo.clas.xml b/src/ui/zcl_abapgit_gui_page_sett_repo.clas.xml new file mode 100644 index 000000000..df679d87c --- /dev/null +++ b/src/ui/zcl_abapgit_gui_page_sett_repo.clas.xml @@ -0,0 +1,16 @@ + + + + + + ZCL_ABAPGIT_GUI_PAGE_SETT_REPO + E + abapGit - Repository Settings + 1 + X + X + X + + + + diff --git a/src/ui/zcl_abapgit_gui_router.clas.abap b/src/ui/zcl_abapgit_gui_router.clas.abap index dafd302db..8a7fb010f 100644 --- a/src/ui/zcl_abapgit_gui_router.clas.abap +++ b/src/ui/zcl_abapgit_gui_router.clas.abap @@ -1,7 +1,7 @@ CLASS zcl_abapgit_gui_router DEFINITION PUBLIC FINAL - CREATE PUBLIC . + CREATE PUBLIC. PUBLIC SECTION. @@ -141,7 +141,7 @@ ENDCLASS. -CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION. +CLASS zcl_abapgit_gui_router IMPLEMENTATION. METHOD abapgit_services_actions. @@ -377,6 +377,7 @@ CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION. CREATE OBJECT lo_code_inspector_page EXPORTING io_repo = lo_repo. + ri_page = lo_code_inspector_page. ELSEIF lo_repo->get_selected_branch( ) CP zif_abapgit_definitions=>c_git_branch-tags. lv_show_create_branch_popup = abap_true. @@ -406,7 +407,6 @@ CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION. IF lv_show_create_branch_popup = abap_true. - lv_answer = zcl_abapgit_ui_factory=>get_popups( )->popup_to_confirm( iv_titlebar = lv_question_title iv_text_question = lv_question_text @@ -416,7 +416,7 @@ CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION. iv_icon_button_2 = 'ICON_CANCEL' iv_default_button = '2' iv_display_cancel_button = abap_false ). - IF lv_answer = 1. + IF lv_answer = '1'. TRY. zcl_abapgit_services_git=>create_branch( iv_key = lo_repo->get_key( ) ). CATCH zcx_abapgit_cancel. @@ -431,7 +431,6 @@ CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION. ri_page = lo_page_repo. ENDIF. - ENDMETHOD. @@ -655,11 +654,14 @@ CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION. zcl_abapgit_services_repo=>transport_to_branch( lv_key ). rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. WHEN zif_abapgit_definitions=>c_action-repo_settings. " Repo settings - CREATE OBJECT rs_handled-page TYPE zcl_abapgit_gui_page_repo_sett - EXPORTING - io_repo = zcl_abapgit_repo_srv=>get_instance( )->get( lv_key ). - - rs_handled-state = zcl_abapgit_gui=>c_event_state-new_page. + rs_handled-page = zcl_abapgit_gui_page_sett_repo=>create( lo_repo ). + rs_handled-state = get_state_settings( ii_event ). + WHEN zif_abapgit_definitions=>c_action-repo_local_settings. " Local repo settings + rs_handled-page = zcl_abapgit_gui_page_sett_locl=>create( lo_repo ). + rs_handled-state = get_state_settings( ii_event ). + WHEN zif_abapgit_definitions=>c_action-repo_infos. " Repo infos + rs_handled-page = zcl_abapgit_gui_page_sett_info=>create( lo_repo ). + rs_handled-state = get_state_settings( ii_event ). WHEN zif_abapgit_definitions=>c_action-repo_log. " Repo log li_log = lo_repo->get_log( ). zcl_abapgit_log_viewer=>show_log( li_log ). diff --git a/src/zif_abapgit_definitions.intf.abap b/src/zif_abapgit_definitions.intf.abap index b121b5144..37387008d 100644 --- a/src/zif_abapgit_definitions.intf.abap +++ b/src/zif_abapgit_definitions.intf.abap @@ -420,6 +420,8 @@ INTERFACE zif_abapgit_definitions repo_refresh TYPE string VALUE 'repo_refresh', repo_remove TYPE string VALUE 'repo_remove', repo_settings TYPE string VALUE 'repo_settings', + repo_local_settings TYPE string VALUE 'repo_local_settings', + repo_infos TYPE string VALUE 'repo_infos', repo_purge TYPE string VALUE 'repo_purge', repo_newonline TYPE string VALUE 'repo_newonline', repo_newoffline TYPE string VALUE 'repo_newoffline',