From cefc4dde7a6dce7bdeb00f9a0278bc2977a9a056 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Tue, 19 Mar 2024 07:04:47 +0200 Subject: [PATCH] Code inspector pages improvements (#6862) --- src/ui/core/zcl_abapgit_html.clas.abap | 37 +- .../zcl_abapgit_html.clas.testclasses.abap | 22 +- src/ui/core/zif_abapgit_html.intf.abap | 20 + .../flow/zcl_abapgit_gui_page_flow.clas.abap | 1 + src/ui/lib/zcl_abapgit_gui_page_hoc.clas.abap | 16 +- src/ui/lib/zcl_abapgit_html_table.clas.abap | 161 ++++- ...l_abapgit_html_table.clas.testclasses.abap | 173 ++++- src/ui/lib/zif_abapgit_html_table.intf.abap | 9 + .../zcl_abapgit_gui_page_code_insp.clas.abap | 124 ++-- .../zcl_abapgit_gui_page_codi_base.clas.abap | 615 +++++++++++++----- .../zcl_abapgit_gui_page_syntax.clas.abap | 57 +- .../zcl_abapgit_gui_page_stage.clas.abap | 10 +- .../routing/zcl_abapgit_gui_router.clas.abap | 5 +- src/ui/zabapgit_css_common.w3mi.data.css | 103 ++- .../zabapgit_css_theme_default.w3mi.data.css | 41 +- 15 files changed, 1055 insertions(+), 339 deletions(-) diff --git a/src/ui/core/zcl_abapgit_html.clas.abap b/src/ui/core/zcl_abapgit_html.clas.abap index 9b76b33ce..003a52868 100644 --- a/src/ui/core/zcl_abapgit_html.clas.abap +++ b/src/ui/core/zcl_abapgit_html.clas.abap @@ -29,6 +29,11 @@ CLASS zcl_abapgit_html DEFINITION iv_checked TYPE abap_bool OPTIONAL RETURNING VALUE(rv_html) TYPE string . + CLASS-METHODS parse_data_attr + IMPORTING + iv_str TYPE string OPTIONAL + RETURNING + VALUE(rs_data_attr) TYPE zif_abapgit_html=>ty_data_attr . PROTECTED SECTION. PRIVATE SECTION. @@ -77,7 +82,7 @@ ENDCLASS. -CLASS zcl_abapgit_html IMPLEMENTATION. +CLASS ZCL_ABAPGIT_HTML IMPLEMENTATION. METHOD checkbox. @@ -232,6 +237,16 @@ CLASS zcl_abapgit_html IMPLEMENTATION. ENDMETHOD. + METHOD parse_data_attr. + + SPLIT iv_str AT '=' INTO rs_data_attr-name rs_data_attr-value. + IF rs_data_attr-name IS INITIAL. + CLEAR rs_data_attr. + ENDIF. + + ENDMETHOD. + + METHOD study_line. DATA: lv_line TYPE string, @@ -462,6 +477,17 @@ CLASS zcl_abapgit_html IMPLEMENTATION. ENDMETHOD. + METHOD zif_abapgit_html~div. + zif_abapgit_html~wrap( + iv_tag = 'div' + iv_content = iv_content + ii_content = ii_content + iv_id = iv_id + iv_class = iv_class ). + ri_self = me. + ENDMETHOD. + + METHOD zif_abapgit_html~icon. rv_str = icon( @@ -512,6 +538,7 @@ CLASS zcl_abapgit_html IMPLEMENTATION. ii_content = ii_content iv_id = iv_id iv_class = iv_class + is_data_attr = is_data_attr iv_hint = iv_hint ). ri_self = me. ENDMETHOD. @@ -525,6 +552,7 @@ CLASS zcl_abapgit_html IMPLEMENTATION. ii_content = ii_content iv_id = iv_id iv_class = iv_class + is_data_attr = is_data_attr iv_hint = iv_hint ). ri_self = me. ENDMETHOD. @@ -537,6 +565,7 @@ CLASS zcl_abapgit_html IMPLEMENTATION. DATA: lv_class TYPE string, lv_id TYPE string, + lv_data_attr TYPE string, lv_title TYPE string. IF iv_id IS NOT INITIAL. @@ -551,7 +580,11 @@ CLASS zcl_abapgit_html IMPLEMENTATION. lv_title = | title="{ iv_hint }"|. ENDIF. - lv_open_tag = |<{ iv_tag }{ lv_id }{ lv_class }{ lv_title }>|. + IF is_data_attr IS NOT INITIAL. + lv_data_attr = | data-{ is_data_attr-name }="{ is_data_attr-value }"|. + ENDIF. + + lv_open_tag = |<{ iv_tag }{ lv_id }{ lv_class }{ lv_data_attr }{ lv_title }>|. lv_close_tag = ||. IF ii_content IS NOT BOUND AND iv_content IS INITIAL. diff --git a/src/ui/core/zcl_abapgit_html.clas.testclasses.abap b/src/ui/core/zcl_abapgit_html.clas.testclasses.abap index 4afe10fca..1e97e3232 100644 --- a/src/ui/core/zcl_abapgit_html.clas.testclasses.abap +++ b/src/ui/core/zcl_abapgit_html.clas.testclasses.abap @@ -217,18 +217,24 @@ CLASS ltcl_html IMPLEMENTATION. iv_tag = 'td' iv_content = 'Hello' iv_format_single_line = abap_true ). + mo_html->wrap( + iv_tag = 'td' + iv_content = 'Hello' + is_data_attr = zcl_abapgit_html=>parse_data_attr( 'id=123' ) + iv_format_single_line = abap_true ). cl_abap_unit_assert=>assert_equals( act = mo_html->render( ) exp = - '' && cl_abap_char_utilities=>newline && - '' && cl_abap_char_utilities=>newline && - ' Hello' && cl_abap_char_utilities=>newline && - '' && cl_abap_char_utilities=>newline && - '' && cl_abap_char_utilities=>newline && - ' Hello' && cl_abap_char_utilities=>newline && - '' && cl_abap_char_utilities=>newline && - 'Hello' ). + |\n| && + |\n| && + | Hello\n| && + |\n| && + |\n| && + | Hello\n| && + |\n| && + |Hello\n| && + |Hello| ). ENDMETHOD. diff --git a/src/ui/core/zif_abapgit_html.intf.abap b/src/ui/core/zif_abapgit_html.intf.abap index 4393b537d..5c00ef8ee 100644 --- a/src/ui/core/zif_abapgit_html.intf.abap +++ b/src/ui/core/zif_abapgit_html.intf.abap @@ -1,5 +1,11 @@ INTERFACE zif_abapgit_html PUBLIC. + TYPES: + BEGIN OF ty_data_attr, + name TYPE string, + value TYPE string, + END OF ty_data_attr. + CONSTANTS: BEGIN OF c_action_type, sapevent TYPE c VALUE 'E', @@ -104,6 +110,7 @@ INTERFACE zif_abapgit_html PUBLIC. !iv_class TYPE string OPTIONAL !iv_hint TYPE string OPTIONAL !iv_format_single_line TYPE abap_bool DEFAULT abap_false + !is_data_attr TYPE ty_data_attr OPTIONAL RETURNING VALUE(ri_self) TYPE REF TO zif_abapgit_html. @@ -115,6 +122,7 @@ INTERFACE zif_abapgit_html PUBLIC. !iv_class TYPE string OPTIONAL !iv_hint TYPE string OPTIONAL !iv_format_single_line TYPE abap_bool DEFAULT abap_true + !is_data_attr TYPE ty_data_attr OPTIONAL PREFERRED PARAMETER iv_content RETURNING VALUE(ri_self) TYPE REF TO zif_abapgit_html. @@ -127,6 +135,18 @@ INTERFACE zif_abapgit_html PUBLIC. !iv_class TYPE string OPTIONAL !iv_hint TYPE string OPTIONAL !iv_format_single_line TYPE abap_bool DEFAULT abap_true + !is_data_attr TYPE ty_data_attr OPTIONAL + PREFERRED PARAMETER iv_content + RETURNING + VALUE(ri_self) TYPE REF TO zif_abapgit_html. + + METHODS div + IMPORTING + !iv_content TYPE string OPTIONAL + !ii_content TYPE REF TO zif_abapgit_html OPTIONAL + !iv_id TYPE string OPTIONAL + !iv_class TYPE string OPTIONAL + !is_data_attr TYPE ty_data_attr OPTIONAL PREFERRED PARAMETER iv_content RETURNING VALUE(ri_self) TYPE REF TO zif_abapgit_html. diff --git a/src/ui/flow/zcl_abapgit_gui_page_flow.clas.abap b/src/ui/flow/zcl_abapgit_gui_page_flow.clas.abap index 4afb72faa..675e3da25 100644 --- a/src/ui/flow/zcl_abapgit_gui_page_flow.clas.abap +++ b/src/ui/flow/zcl_abapgit_gui_page_flow.clas.abap @@ -226,6 +226,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_FLOW IMPLEMENTATION. iv_key = lv_key ). rs_handled-page = zcl_abapgit_gui_page_stage=>create( + ii_force_refresh = abap_false io_repo = lo_online ii_obj_filter = lo_filter ). diff --git a/src/ui/lib/zcl_abapgit_gui_page_hoc.clas.abap b/src/ui/lib/zcl_abapgit_gui_page_hoc.clas.abap index 9f0972963..2a8ae8e53 100644 --- a/src/ui/lib/zcl_abapgit_gui_page_hoc.clas.abap +++ b/src/ui/lib/zcl_abapgit_gui_page_hoc.clas.abap @@ -54,7 +54,7 @@ ENDCLASS. -CLASS zcl_abapgit_gui_page_hoc IMPLEMENTATION. +CLASS ZCL_ABAPGIT_GUI_PAGE_HOC IMPLEMENTATION. METHOD constructor. @@ -93,6 +93,20 @@ CLASS zcl_abapgit_gui_page_hoc IMPLEMENTATION. ls_control-extra_js_url = iv_extra_js_url. ls_control-show_as_modal = iv_show_as_modal. + IF ls_control-page_menu_provider IS NOT BOUND. " try component itself + TRY. + ls_control-page_menu_provider ?= ii_child_component. + CATCH cx_sy_move_cast_error. + ENDTRY. + ENDIF. + + IF ls_control-page_title_provider IS NOT BOUND. " try component itself + TRY. + ls_control-page_title_provider ?= ii_child_component. + CATCH cx_sy_move_cast_error. + ENDTRY. + ENDIF. + CREATE OBJECT lo_page EXPORTING ii_child_component = ii_child_component diff --git a/src/ui/lib/zcl_abapgit_html_table.clas.abap b/src/ui/lib/zcl_abapgit_html_table.clas.abap index 3bdf3816e..81be70d4c 100644 --- a/src/ui/lib/zcl_abapgit_html_table.clas.abap +++ b/src/ui/lib/zcl_abapgit_html_table.clas.abap @@ -8,45 +8,67 @@ CLASS zcl_abapgit_html_table DEFINITION CLASS-METHODS create IMPORTING - !ii_renderer TYPE REF TO zif_abapgit_html_table + !ii_renderer TYPE REF TO zif_abapgit_html_table OPTIONAL RETURNING VALUE(ro_instance) TYPE REF TO zcl_abapgit_html_table . " probably th css_class " maybe auto class for td METHODS define_column IMPORTING - !iv_column_id TYPE string + !iv_column_id TYPE string !iv_column_title TYPE string OPTIONAL - !iv_from_field TYPE abap_compname OPTIONAL + !iv_from_field TYPE abap_compname OPTIONAL + !iv_sortable TYPE abap_bool DEFAULT abap_true RETURNING - VALUE(ro_self) TYPE REF TO zcl_abapgit_html_table . + VALUE(ro_self) TYPE REF TO zcl_abapgit_html_table . " Maybe also data_provider " Record Limit METHODS render IMPORTING + !ii_renderer TYPE REF TO zif_abapgit_html_table OPTIONAL + !it_data TYPE ANY TABLE !iv_id TYPE csequence OPTIONAL !iv_css_class TYPE csequence OPTIONAL - !it_data TYPE ANY TABLE + !iv_with_cids TYPE abap_bool DEFAULT abap_false + !is_sorting_state TYPE zif_abapgit_html_table=>ty_sorting_state OPTIONAL + !iv_wrap_in_div TYPE string OPTIONAL " div class name RETURNING VALUE(ri_html) TYPE REF TO zif_abapgit_html RAISING zcx_abapgit_exception . + " Static utils + CLASS-METHODS detect_sorting_request + IMPORTING + iv_event TYPE string + RETURNING + VALUE(rs_sorting_request) TYPE zif_abapgit_html_table=>ty_sorting_state. + PROTECTED SECTION. PRIVATE SECTION. + CONSTANTS c_sort_by_event_prefix TYPE string VALUE `sort_by:`. + CONSTANTS c_sort_by_event_regex TYPE string VALUE `^sort_by:\w+:(asc|dsc)$`. + TYPES: BEGIN OF ty_column, - column_id TYPE string, + column_id TYPE string, column_title TYPE string, - from_field TYPE abap_compname, + from_field TYPE abap_compname, + sortable TYPE abap_bool, END OF ty_column, ty_columns TYPE STANDARD TABLE OF ty_column WITH KEY column_id. - DATA mi_renderer TYPE REF TO zif_abapgit_html_table. DATA mt_columns TYPE ty_columns. DATA mi_html TYPE REF TO zif_abapgit_html. + DATA mv_with_cids TYPE abap_bool. + DATA mv_table_id TYPE string. + DATA ms_sorting_state TYPE zif_abapgit_html_table=>ty_sorting_state. + + " potentially receive from outside + DATA mv_sort_span_class TYPE string VALUE `sort-arrow`. + DATA mv_sort_active_class TYPE string VALUE `sort-active`. METHODS render_thead RAISING @@ -65,6 +87,20 @@ CLASS zcl_abapgit_html_table DEFINITION RAISING zcx_abapgit_exception . + METHODS render_column_title + IMPORTING + is_col TYPE ty_column + RETURNING + VALUE(rv_text) TYPE string + RAISING + zcx_abapgit_exception . + + CLASS-METHODS cid_attr + IMPORTING + iv_column_id TYPE string + RETURNING + VALUE(rs_data_attr) TYPE zif_abapgit_html=>ty_data_attr. + ENDCLASS. @@ -72,8 +108,15 @@ ENDCLASS. CLASS ZCL_ABAPGIT_HTML_TABLE IMPLEMENTATION. + METHOD cid_attr. + + rs_data_attr-name = 'cid'. + rs_data_attr-value = iv_column_id. + + ENDMETHOD. + + METHOD create. - ASSERT ii_renderer IS BOUND. CREATE OBJECT ro_instance. ro_instance->mi_renderer = ii_renderer. ENDMETHOD. @@ -90,6 +133,27 @@ CLASS ZCL_ABAPGIT_HTML_TABLE IMPLEMENTATION. -column_id = iv_column_id. -column_title = iv_column_title. -from_field = to_upper( iv_from_field ). + -sortable = iv_sortable. + + ENDMETHOD. + + + METHOD detect_sorting_request. + + DATA lv_req TYPE string. + + IF find( + val = iv_event + regex = c_sort_by_event_regex ) = 0. + + lv_req = replace( + val = iv_event + sub = c_sort_by_event_prefix + with = '' ). + SPLIT lv_req AT ':' INTO rs_sorting_request-column_id lv_req. + rs_sorting_request-descending = boolc( lv_req = 'dsc' ). + + ENDIF. ENDMETHOD. @@ -98,6 +162,16 @@ CLASS ZCL_ABAPGIT_HTML_TABLE IMPLEMENTATION. DATA lv_attrs TYPE string. + IF ii_renderer IS BOUND. + mi_renderer = ii_renderer. + ENDIF. + + ASSERT mi_renderer IS BOUND. + + mv_with_cids = iv_with_cids. + mv_table_id = iv_id. + ms_sorting_state = is_sorting_state. + IF iv_id IS NOT INITIAL. lv_attrs = lv_attrs && | id="{ iv_id }"|. ENDIF. @@ -109,11 +183,56 @@ CLASS ZCL_ABAPGIT_HTML_TABLE IMPLEMENTATION. CREATE OBJECT mi_html TYPE zcl_abapgit_html. ri_html = mi_html. + IF iv_wrap_in_div IS NOT INITIAL. + mi_html->add( |
| ). + ENDIF. + mi_html->add( || ). render_thead( ). render_tbody( it_data ). mi_html->add( '' ). + IF iv_wrap_in_div IS NOT INITIAL. + mi_html->add( '
' ). + ENDIF. + + ENDMETHOD. + + + METHOD render_column_title. + + DATA lv_direction TYPE string. + DATA lv_arrow TYPE string. + DATA lv_sort_active TYPE string. + + IF is_col-sortable = abap_true AND ms_sorting_state IS NOT INITIAL. + + IF is_col-column_id = ms_sorting_state-column_id AND ms_sorting_state-descending = abap_false. + lv_direction = 'dsc'. + ELSE. + lv_direction = 'asc'. + ENDIF. + + IF is_col-column_id = ms_sorting_state-column_id AND ms_sorting_state-descending = abap_true. + lv_arrow = '▴'. " arrow up + ELSE. + lv_arrow = '▾'. " arrow down + ENDIF. + + IF is_col-column_id = ms_sorting_state-column_id. + lv_sort_active = | { mv_sort_active_class }|. + ENDIF. + + rv_text = mi_html->a( + iv_txt = is_col-column_title + iv_act = |{ c_sort_by_event_prefix }{ is_col-column_id }:{ lv_direction }| ). + + rv_text = rv_text && |{ lv_arrow }|. + + ELSE. + rv_text = is_col-column_title. + ENDIF. + ENDMETHOD. @@ -121,6 +240,7 @@ CLASS ZCL_ABAPGIT_HTML_TABLE IMPLEMENTATION. DATA ls_render TYPE zif_abapgit_html_table=>ty_cell_render. DATA lv_dummy TYPE string. + DATA ls_cid TYPE zif_abapgit_html=>ty_data_attr. FIELD-SYMBOLS LIKE LINE OF mt_columns. FIELD-SYMBOLS TYPE any. @@ -140,14 +260,22 @@ CLASS ZCL_ABAPGIT_HTML_TABLE IMPLEMENTATION. ELSE. ASSIGN lv_dummy TO . ENDIF. + ls_render = mi_renderer->render_cell( + iv_table_id = mv_table_id iv_row_index = iv_row_index is_row = is_row iv_column_id = -column_id - iv_value = ). + iv_value = |{ }| ). + + IF mv_with_cids = abap_true. + ls_cid = cid_attr( -column_id ). + ENDIF. + mi_html->td( iv_content = ls_render-content ii_content = ls_render-html + is_data_attr = ls_cid iv_class = ls_render-css_class ). ENDLOOP. @@ -167,12 +295,16 @@ CLASS ZCL_ABAPGIT_HTML_TABLE IMPLEMENTATION. LOOP AT it_data ASSIGNING . lv_index = sy-tabix. ls_row_attrs = mi_renderer->get_row_attrs( + iv_table_id = mv_table_id iv_row_index = lv_index is_row = ). CLEAR lv_row_attrs. IF ls_row_attrs-css_class IS NOT INITIAL. lv_row_attrs = lv_row_attrs && | class="{ ls_row_attrs-css_class }"|. ENDIF. + IF ls_row_attrs-data IS NOT INITIAL. + lv_row_attrs = lv_row_attrs && | data-{ ls_row_attrs-data-name }="{ ls_row_attrs-data-value }"|. + ENDIF. mi_html->add( || ). render_row( iv_row_index = lv_index @@ -188,12 +320,19 @@ CLASS ZCL_ABAPGIT_HTML_TABLE IMPLEMENTATION. METHOD render_thead. FIELD-SYMBOLS LIKE LINE OF mt_columns. + DATA ls_cid TYPE zif_abapgit_html=>ty_data_attr. mi_html->add( '' ). mi_html->add( '' ). LOOP AT mt_columns ASSIGNING . - mi_html->th( -column_title ). + IF mv_with_cids = abap_true. + ls_cid = cid_attr( -column_id ). + ENDIF. + + mi_html->th( + iv_content = render_column_title( ) + is_data_attr = ls_cid ). ENDLOOP. mi_html->add( '' ). diff --git a/src/ui/lib/zcl_abapgit_html_table.clas.testclasses.abap b/src/ui/lib/zcl_abapgit_html_table.clas.testclasses.abap index f2a663d4d..2291048ba 100644 --- a/src/ui/lib/zcl_abapgit_html_table.clas.testclasses.abap +++ b/src/ui/lib/zcl_abapgit_html_table.clas.testclasses.abap @@ -11,36 +11,67 @@ CLASS ltcl_test_simple_table DEFINITION FINAL col2 TYPE i, col3 TYPE i, col4 TYPE REF TO data, - END OF ty_simple_data. + END OF ty_simple_data, + ty_simple_data_tab TYPE STANDARD TABLE OF ty_simple_data WITH DEFAULT KEY. METHODS simple_render FOR TESTING RAISING zcx_abapgit_exception. + METHODS with_cids FOR TESTING RAISING zcx_abapgit_exception. + METHODS with_sort FOR TESTING RAISING zcx_abapgit_exception. + + METHODS test_data_set + RETURNING + VALUE(rt_data_set) TYPE ty_simple_data_tab. ENDCLASS. CLASS ltcl_test_simple_table IMPLEMENTATION. METHOD zif_abapgit_html_table~get_row_attrs. - rs_attrs-css_class = |r{ iv_row_index }|. + IF iv_table_id = 'simple'. + rs_attrs-css_class = |r{ iv_row_index }|. + ELSEIF iv_table_id = 'with-cids'. + rs_attrs-data = zcl_abapgit_html=>parse_data_attr( |attr={ iv_row_index }| ). + ENDIF. ENDMETHOD. METHOD zif_abapgit_html_table~render_cell. - rs_render-css_class = 'cell'. - IF iv_column_id = 'colX'. - IF iv_row_index = 2. - rs_render-html = zcl_abapgit_html=>create( )->add( 'XHTML' ). + IF iv_table_id = 'simple'. + rs_render-css_class = 'cell'. + IF iv_column_id = 'colX'. + IF iv_row_index = 2. + rs_render-html = zcl_abapgit_html=>create( )->add( 'XHTML' ). + ELSE. + rs_render-content = 'X'. + ENDIF. ELSE. - rs_render-content = 'X'. + rs_render-content = |{ iv_value }|. ENDIF. - ELSE. - rs_render-content = |{ iv_value }|. + ELSEIF iv_table_id = 'with-cids'. + rs_render-content = iv_value. + ELSEIF iv_table_id = 'with-sort'. + rs_render-content = iv_value. ENDIF. + + ENDMETHOD. + + METHOD test_data_set. + + FIELD-SYMBOLS LIKE LINE OF rt_data_set. + + APPEND INITIAL LINE TO rt_data_set ASSIGNING . + -col1 = 'Hello'. + -col2 = 1. + -col3 = 10. + APPEND INITIAL LINE TO rt_data_set ASSIGNING . + -col1 = 'World'. + -col2 = 2. + -col3 = 20. + ENDMETHOD. METHOD simple_render. DATA lo_tab TYPE REF TO zcl_abapgit_html_table. - DATA lt_dummy_data TYPE TABLE OF ty_simple_data. DATA lv_html_act TYPE string. DATA li_html_exp TYPE REF TO zif_abapgit_html. - FIELD-SYMBOLS LIKE LINE OF lt_dummy_data. lo_tab = zcl_abapgit_html_table=>create( me )->define_column( @@ -52,24 +83,15 @@ CLASS ltcl_test_simple_table IMPLEMENTATION. iv_from_field = 'col3' )->define_column( 'colX' ). - APPEND INITIAL LINE TO lt_dummy_data ASSIGNING . - -col1 = 'Hello'. - -col2 = 1. - -col3 = 10. - APPEND INITIAL LINE TO lt_dummy_data ASSIGNING . - -col1 = 'World'. - -col2 = 2. - -col3 = 20. - lv_html_act = lo_tab->render( - iv_id = 'tabid' + iv_id = 'simple' iv_css_class = 'tabclass' - it_data = lt_dummy_data )->render( ). + it_data = test_data_set( ) )->render( ). CREATE OBJECT li_html_exp TYPE zcl_abapgit_html. li_html_exp->add( - '' )->add( + '
' )->add( '' )->add( '' )->add( '' )->add( @@ -99,4 +121,109 @@ CLASS ltcl_test_simple_table IMPLEMENTATION. ENDMETHOD. + METHOD with_cids. + + DATA lo_tab TYPE REF TO zcl_abapgit_html_table. + DATA lv_html_act TYPE string. + DATA li_html_exp TYPE REF TO zif_abapgit_html. + + lo_tab = zcl_abapgit_html_table=>create( me + )->define_column( + iv_column_id = 'col1' + iv_column_title = 'Col 1' + )->define_column( + iv_column_id = 'col2' + iv_column_title = 'Col 2' ). + + lv_html_act = lo_tab->render( + iv_id = 'with-cids' + iv_with_cids = abap_true + it_data = test_data_set( ) )->render( ). + + CREATE OBJECT li_html_exp TYPE zcl_abapgit_html. + + li_html_exp->add( + '
Col 1
' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '
Col 1Col 2
Hello1
World2
' ). + + cl_abap_unit_assert=>assert_equals( + act = lv_html_act + exp = li_html_exp->render( ) ). + + ENDMETHOD. + + METHOD with_sort. + + DATA lo_tab TYPE REF TO zcl_abapgit_html_table. + DATA lv_html_act TYPE string. + DATA li_html_exp TYPE REF TO zif_abapgit_html. + DATA ls_sort TYPE zif_abapgit_html_table=>ty_sorting_state. + + lo_tab = zcl_abapgit_html_table=>create( me + )->define_column( + iv_column_id = 'col1' + iv_column_title = 'Col 1' + )->define_column( + iv_column_id = 'col2' + iv_column_title = 'Col 2' + )->define_column( + iv_column_id = 'col3' + iv_column_title = 'Col 3' + iv_sortable = abap_false ). + + ls_sort-column_id = 'col1'. + + lv_html_act = lo_tab->render( + is_sorting_state = ls_sort + iv_id = 'with-sort' + it_data = test_data_set( ) )->render( ). + + CREATE OBJECT li_html_exp TYPE zcl_abapgit_html. + + li_html_exp->add( + '' )->add( + '' )->add( + '' )->add( + '' + )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '' )->add( + '
Col 1Col 2Col 3
Hello110
World220
' ). + + cl_abap_unit_assert=>assert_equals( + act = lv_html_act + exp = li_html_exp->render( ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/ui/lib/zif_abapgit_html_table.intf.abap b/src/ui/lib/zif_abapgit_html_table.intf.abap index 46ac5a882..cc5031d79 100644 --- a/src/ui/lib/zif_abapgit_html_table.intf.abap +++ b/src/ui/lib/zif_abapgit_html_table.intf.abap @@ -4,6 +4,7 @@ INTERFACE zif_abapgit_html_table TYPES: BEGIN OF ty_row_attrs, css_class TYPE string, + data TYPE zif_abapgit_html=>ty_data_attr, END OF ty_row_attrs. TYPES: @@ -13,8 +14,15 @@ INTERFACE zif_abapgit_html_table html TYPE REF TO zif_abapgit_html, END OF ty_cell_render. + TYPES: + BEGIN OF ty_sorting_state, + column_id TYPE string, + descending TYPE abap_bool, + END OF ty_sorting_state. + METHODS get_row_attrs IMPORTING + iv_table_id TYPE string iv_row_index TYPE i is_row TYPE any RETURNING @@ -24,6 +32,7 @@ INTERFACE zif_abapgit_html_table METHODS render_cell IMPORTING + iv_table_id TYPE string iv_row_index TYPE i is_row TYPE any iv_column_id TYPE string diff --git a/src/ui/pages/codi/zcl_abapgit_gui_page_code_insp.clas.abap b/src/ui/pages/codi/zcl_abapgit_gui_page_code_insp.clas.abap index 28d75594a..1c9182175 100644 --- a/src/ui/pages/codi/zcl_abapgit_gui_page_code_insp.clas.abap +++ b/src/ui/pages/codi/zcl_abapgit_gui_page_code_insp.clas.abap @@ -7,6 +7,7 @@ CLASS zcl_abapgit_gui_page_code_insp DEFINITION PUBLIC SECTION. INTERFACES: + zif_abapgit_gui_page_title, zif_abapgit_gui_event_handler, zif_abapgit_gui_hotkeys, zif_abapgit_gui_menu_provider, @@ -23,22 +24,20 @@ CLASS zcl_abapgit_gui_page_code_insp DEFINITION RAISING zcx_abapgit_exception. - METHODS: - constructor - IMPORTING - io_repo TYPE REF TO zcl_abapgit_repo - io_stage TYPE REF TO zcl_abapgit_stage OPTIONAL - iv_check_variant TYPE sci_chkv OPTIONAL - iv_raise_when_no_results TYPE abap_bool DEFAULT abap_false - RAISING - zcx_abapgit_exception. + METHODS constructor + IMPORTING + io_repo TYPE REF TO zcl_abapgit_repo + io_stage TYPE REF TO zcl_abapgit_stage OPTIONAL + iv_check_variant TYPE sci_chkv OPTIONAL + iv_raise_when_no_results TYPE abap_bool DEFAULT abap_false + RAISING + zcx_abapgit_exception. PROTECTED SECTION. PRIVATE SECTION. - DATA: - mo_stage TYPE REF TO zcl_abapgit_stage, - mv_check_variant TYPE sci_chkv. + DATA mo_stage TYPE REF TO zcl_abapgit_stage. + DATA mv_check_variant TYPE sci_chkv. METHODS: run_code_inspector @@ -62,11 +61,16 @@ CLASS zcl_abapgit_gui_page_code_insp DEFINITION determine_check_variant RAISING zcx_abapgit_exception. + + METHODS status + RETURNING + VALUE(rv_status) TYPE zif_abapgit_definitions=>ty_sci_result. + ENDCLASS. -CLASS zcl_abapgit_gui_page_code_insp IMPLEMENTATION. +CLASS ZCL_ABAPGIT_GUI_PAGE_CODE_INSP IMPLEMENTATION. METHOD ask_user_for_check_variant. @@ -81,6 +85,7 @@ CLASS zcl_abapgit_gui_page_code_insp IMPLEMENTATION. METHOD constructor. + super->constructor( ). mo_repo = io_repo. mo_stage = io_stage. @@ -91,6 +96,7 @@ CLASS zcl_abapgit_gui_page_code_insp IMPLEMENTATION. IF mt_result IS INITIAL AND iv_raise_when_no_results = abap_true. zcx_abapgit_exception=>raise( 'No results' ). ENDIF. + ENDMETHOD. @@ -105,10 +111,7 @@ CLASS zcl_abapgit_gui_page_code_insp IMPLEMENTATION. iv_check_variant = iv_check_variant iv_raise_when_no_results = iv_raise_when_no_results. - ri_page = zcl_abapgit_gui_page_hoc=>create( - iv_page_title = 'Code Inspector' - ii_page_menu_provider = lo_component - ii_child_component = lo_component ). + ri_page = zcl_abapgit_gui_page_hoc=>create( lo_component ). ENDMETHOD. @@ -130,8 +133,7 @@ CLASS zcl_abapgit_gui_page_code_insp IMPLEMENTATION. METHOD has_inspection_errors. - READ TABLE mt_result TRANSPORTING NO FIELDS - WITH KEY kind = 'E'. + READ TABLE mt_result TRANSPORTING NO FIELDS WITH KEY kind = 'E'. rv_has_inspection_errors = boolc( sy-subrc = 0 ). ENDMETHOD. @@ -139,15 +141,15 @@ CLASS zcl_abapgit_gui_page_code_insp IMPLEMENTATION. METHOD is_stage_allowed. - rv_is_stage_allowed = boolc( NOT ( mo_repo->get_local_settings( )-block_commit = abap_true - AND has_inspection_errors( ) = abap_true ) ). + rv_is_stage_allowed = boolc( NOT ( + mo_repo->get_local_settings( )-block_commit = abap_true AND has_inspection_errors( ) = abap_true ) ). ENDMETHOD. METHOD run_code_inspector. - DATA: li_code_inspector TYPE REF TO zif_abapgit_code_inspector. + DATA li_code_inspector TYPE REF TO zif_abapgit_code_inspector. li_code_inspector = zcl_abapgit_factory=>get_code_inspector( mo_repo->get_package( ) ). @@ -162,10 +164,26 @@ CLASS zcl_abapgit_gui_page_code_insp IMPLEMENTATION. ENDMETHOD. + METHOD status. + + READ TABLE mt_result TRANSPORTING NO FIELDS WITH KEY kind = 'E'. + IF sy-subrc = 0. + rv_status = zif_abapgit_definitions=>c_sci_result-failed. + ELSE. + READ TABLE mt_result TRANSPORTING NO FIELDS WITH KEY kind = 'W'. + IF sy-subrc = 0. + rv_status = zif_abapgit_definitions=>c_sci_result-warning. + ELSE. + rv_status = zif_abapgit_definitions=>c_sci_result-passed. + ENDIF. + ENDIF. + + ENDMETHOD. + + METHOD zif_abapgit_gui_event_handler~on_event. DATA lo_repo_online TYPE REF TO zcl_abapgit_repo_online. - DATA lv_sci_result TYPE zif_abapgit_definitions=>ty_sci_result. CASE ii_event->mv_action. WHEN c_actions-stage. @@ -173,24 +191,10 @@ CLASS zcl_abapgit_gui_page_code_insp IMPLEMENTATION. lo_repo_online ?= mo_repo. IF is_stage_allowed( ) = abap_true. - " we need to refresh as the source might have changed - lo_repo_online->refresh( ). - - READ TABLE mt_result TRANSPORTING NO FIELDS WITH KEY kind = 'E'. - IF sy-subrc = 0. - lv_sci_result = zif_abapgit_definitions=>c_sci_result-failed. - ELSE. - READ TABLE mt_result TRANSPORTING NO FIELDS WITH KEY kind = 'W'. - IF sy-subrc = 0. - lv_sci_result = zif_abapgit_definitions=>c_sci_result-warning. - ELSE. - lv_sci_result = zif_abapgit_definitions=>c_sci_result-passed. - ENDIF. - ENDIF. rs_handled-page = zcl_abapgit_gui_page_stage=>create( io_repo = lo_repo_online - iv_sci_result = lv_sci_result ). + iv_sci_result = status( ) ). rs_handled-state = zcl_abapgit_gui=>c_event_state-new_page. @@ -268,15 +272,17 @@ CLASS zcl_abapgit_gui_page_code_insp IMPLEMENTATION. " Staging info already available, we can directly " offer to commit - ro_toolbar->add( iv_txt = 'Commit' - iv_act = c_actions-commit - iv_opt = lv_opt ). + ro_toolbar->add( + iv_txt = 'Commit' + iv_act = c_actions-commit + iv_opt = lv_opt ). ELSE. - ro_toolbar->add( iv_txt = 'Stage' - iv_act = c_actions-stage - iv_opt = lv_opt ). + ro_toolbar->add( + iv_txt = 'Stage' + iv_act = c_actions-stage + iv_opt = lv_opt ). ENDIF. @@ -287,36 +293,32 @@ CLASS zcl_abapgit_gui_page_code_insp IMPLEMENTATION. ENDMETHOD. + METHOD zif_abapgit_gui_page_title~get_page_title. + rv_title = 'Code Inspector'. + ENDMETHOD. + + METHOD zif_abapgit_gui_renderable~render. register_handlers( ). 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 ) ). - ri_html->add( `
` ). + ri_html->div( + iv_class = 'repo' + ii_content = zcl_abapgit_gui_chunk_lib=>render_repo_top( + io_repo = mo_repo + iv_show_commit = abap_false ) ). IF mv_check_variant IS INITIAL. ri_html->add( zcl_abapgit_gui_chunk_lib=>render_error( iv_error = 'No check variant supplied.' ) ). RETURN. ENDIF. - ri_html->add( render_variant( + render_ci_report( + ii_html = ri_html iv_variant = mv_check_variant - iv_summary = mv_summary ) ). - - IF lines( mt_result ) = 0. - ri_html->add( '
' ). - ri_html->add( ri_html->icon( 'check' ) ). - ri_html->add( 'No code inspector findings' ). - ri_html->add( '
' ). - ELSE. - render_result( - ii_html = ri_html - it_result = mt_result ). - ENDIF. + iv_success_msg = 'No code inspector findings' ). ENDMETHOD. ENDCLASS. diff --git a/src/ui/pages/codi/zcl_abapgit_gui_page_codi_base.clas.abap b/src/ui/pages/codi/zcl_abapgit_gui_page_codi_base.clas.abap index bc2e1a5fb..35e9835aa 100644 --- a/src/ui/pages/codi/zcl_abapgit_gui_page_codi_base.clas.abap +++ b/src/ui/pages/codi/zcl_abapgit_gui_page_codi_base.clas.abap @@ -3,20 +3,21 @@ CLASS zcl_abapgit_gui_page_codi_base DEFINITION INHERITING FROM zcl_abapgit_gui_component. PUBLIC SECTION. + INTERFACES zif_abapgit_html_table. PROTECTED SECTION. CONSTANTS: BEGIN OF c_actions, rerun TYPE string VALUE 'rerun', - sort_1 TYPE string VALUE 'sort_1', - sort_2 TYPE string VALUE 'sort_2', - sort_3 TYPE string VALUE 'sort_3', stage TYPE string VALUE 'stage', commit TYPE string VALUE 'commit', + filter_kind TYPE string VALUE 'filter_kind', + apply_filter TYPE string VALUE 'apply_filter', END OF c_actions . - DATA mo_repo TYPE REF TO zcl_abapgit_repo . - DATA mt_result TYPE zif_abapgit_code_inspector=>ty_results . + + DATA mo_repo TYPE REF TO zcl_abapgit_repo. + DATA mt_result TYPE zif_abapgit_code_inspector=>ty_results. DATA mv_summary TYPE string. METHODS on_event @@ -27,69 +28,149 @@ CLASS zcl_abapgit_gui_page_codi_base DEFINITION RAISING zcx_abapgit_exception. - METHODS render_variant + METHODS render_ci_report IMPORTING + !ii_html TYPE REF TO zif_abapgit_html + !iv_variant TYPE sci_chkv + !iv_success_msg TYPE string + RAISING + zcx_abapgit_exception. + METHODS render_head + IMPORTING + !ii_html TYPE REF TO zif_abapgit_html !iv_variant TYPE sci_chkv - !iv_summary TYPE string + !iv_summary TYPE string. + METHODS render_detail + IMPORTING + !ii_html TYPE REF TO zif_abapgit_html + !it_result TYPE zif_abapgit_code_inspector=>ty_results + RAISING + zcx_abapgit_exception. + METHODS render_stats + IMPORTING + !ii_html TYPE REF TO zif_abapgit_html + !it_result TYPE zif_abapgit_code_inspector=>ty_results + RAISING + zcx_abapgit_exception. + METHODS render_success + IMPORTING + ii_html TYPE REF TO zif_abapgit_html + iv_message TYPE string. + METHODS build_base_menu RETURNING - VALUE(ri_html) TYPE REF TO zif_abapgit_html . - METHODS render_result + VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar. + + PRIVATE SECTION. + + CONSTANTS c_object_separator TYPE c LENGTH 1 VALUE '|'. + CONSTANTS c_ci_sig TYPE string VALUE 'cinav:'. + CONSTANTS c_limit TYPE i VALUE 500. + DATA mv_filter_kind TYPE string. + DATA ms_sorting_state TYPE zif_abapgit_html_table=>ty_sorting_state. + + TYPES: + BEGIN OF ty_result_view, + kind TYPE zif_abapgit_code_inspector=>ty_result-kind, + obj_type TYPE zif_abapgit_code_inspector=>ty_result-objtype, + location TYPE string, + text TYPE string, + nav TYPE string, + END OF ty_result_view, + ty_view_tab TYPE STANDARD TABLE OF ty_result_view WITH DEFAULT KEY. + + METHODS convert_result_to_view IMPORTING - !ii_html TYPE REF TO zif_abapgit_html - !it_result TYPE zif_abapgit_code_inspector=>ty_results . - METHODS render_result_line + it_result TYPE zif_abapgit_code_inspector=>ty_results + RETURNING + VALUE(rt_view) TYPE ty_view_tab. + METHODS explain_include IMPORTING - !ii_html TYPE REF TO zif_abapgit_html - !is_result TYPE zif_abapgit_code_inspector=>ty_result . + !is_result TYPE zif_abapgit_code_inspector=>ty_result + RETURNING + VALUE(rv_txt) TYPE string. + METHODS render_limit_warning + IMPORTING + !ii_html TYPE REF TO zif_abapgit_html. METHODS build_nav_link IMPORTING !is_result TYPE zif_abapgit_code_inspector=>ty_result RETURNING - VALUE(rv_link) TYPE string . + VALUE(rv_link) TYPE string. METHODS jump IMPORTING !is_item TYPE zif_abapgit_definitions=>ty_item !is_sub_item TYPE zif_abapgit_definitions=>ty_item !iv_line_number TYPE i RAISING - zcx_abapgit_exception . - METHODS build_base_menu - RETURNING - VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar . - PRIVATE SECTION. - CONSTANTS c_object_separator TYPE c LENGTH 1 VALUE '|'. - CONSTANTS c_ci_sig TYPE string VALUE 'cinav:'. + zcx_abapgit_exception. + METHODS apply_sorting + CHANGING + ct_view TYPE ty_view_tab. + METHODS apply_filter_kind + CHANGING + ct_view TYPE ty_view_tab. + METHODS handle_navigation + IMPORTING + iv_link TYPE string + RAISING + zcx_abapgit_exception. + METHODS render_stat + IMPORTING + !ii_html TYPE REF TO zif_abapgit_html + !iv_count TYPE i + !iv_type TYPE string + !iv_title TYPE string + RAISING + zcx_abapgit_exception. + ENDCLASS. -CLASS zcl_abapgit_gui_page_codi_base IMPLEMENTATION. +CLASS ZCL_ABAPGIT_GUI_PAGE_CODI_BASE IMPLEMENTATION. + + + METHOD apply_filter_kind. + + CASE mv_filter_kind. + WHEN 'error'. + DELETE ct_view WHERE kind <> 'E'. + WHEN 'warn'. + DELETE ct_view WHERE kind <> 'W'. + WHEN 'info'. + DELETE ct_view WHERE NOT ( kind = 'E' OR kind = 'W' ). + WHEN OTHERS. + RETURN. + ENDCASE. + + ENDMETHOD. + + + METHOD apply_sorting. + + DATA lv_field TYPE abap_compname. + + CASE ms_sorting_state-column_id. + WHEN 'kind' OR 'obj_type' OR 'location' OR 'text'. + lv_field = to_upper( ms_sorting_state-column_id ). + WHEN OTHERS. + RETURN. + ENDCASE. + + IF ms_sorting_state-descending = abap_true. + SORT ct_view BY (lv_field) DESCENDING. + ELSE. + SORT ct_view BY (lv_field) ASCENDING. + ENDIF. + + ENDMETHOD. METHOD build_base_menu. - DATA: - lo_sort_menu TYPE REF TO zcl_abapgit_html_toolbar. - - CREATE OBJECT lo_sort_menu. - - lo_sort_menu->add( - iv_txt = 'By Object, Check, Sub-object' - iv_act = c_actions-sort_1 - )->add( - iv_txt = 'By Object, Sub-object, Line' - iv_act = c_actions-sort_2 - )->add( - iv_txt = 'By Check, Object, Sub-object' - iv_act = c_actions-sort_3 ). - - CREATE OBJECT ro_menu. - - ro_menu->add( iv_txt = 'Sort' - io_sub = lo_sort_menu ). - - ro_menu->add( iv_txt = 'Re-Run' - iv_act = c_actions-rerun ). + ro_menu = zcl_abapgit_html_toolbar=>create( )->add( + iv_txt = 'Re-Run' + iv_act = c_actions-rerun ). ENDMETHOD. @@ -104,6 +185,112 @@ CLASS zcl_abapgit_gui_page_codi_base IMPLEMENTATION. ENDMETHOD. + METHOD convert_result_to_view. + + FIELD-SYMBOLS LIKE LINE OF it_result. + FIELD-SYMBOLS LIKE LINE OF rt_view. + DATA lv_line TYPE i. + + LOOP AT it_result ASSIGNING . + APPEND INITIAL LINE TO rt_view ASSIGNING . + -kind = -kind. + -obj_type = -objtype. + -nav = build_nav_link( ). + -text = -text. + + IF -sobjname IS INITIAL OR + ( -sobjname = -objname AND + -sobjtype = -objtype ). + -location = to_lower( -objname ). + ELSEIF -objtype = 'CLAS' OR + ( -objtype = 'PROG' AND NOT -sobjname+30(*) IS INITIAL ). + -location = explain_include( ). + ENDIF. + + IF -location IS INITIAL. " Fallback to a reasonable default + -location = to_lower( |{ -objname } > { -sobjtype } { -sobjname }| ). + ENDIF. + + lv_line = -line. " convert from numc to integer + -location = |{ -location } @{ lv_line }|. + + ENDLOOP. + + ENDMETHOD. + + + METHOD explain_include. + + DATA ls_mtdkey TYPE seocpdkey. + + TRY. + CASE is_result-sobjname+30(*). + WHEN 'CCDEF'. + rv_txt = |{ to_lower( is_result-objname ) }: Local Definitions|. + WHEN 'CCIMP'. + rv_txt = |{ to_lower( is_result-objname ) }: Local Implementations|. + WHEN 'CCMAC'. + rv_txt = |{ to_lower( is_result-objname ) }: Macros|. + WHEN 'CCAU'. + rv_txt = |{ to_lower( is_result-objname ) }: Test Classes|. + WHEN 'CU'. + rv_txt = |{ to_lower( is_result-objname ) }: Public Section|. + WHEN 'CO'. + rv_txt = |{ to_lower( is_result-objname ) }: Protected Section|. + WHEN 'CI'. + rv_txt = |{ to_lower( is_result-objname ) }: Private Section|. + WHEN OTHERS. + cl_oo_classname_service=>get_method_by_include( + EXPORTING + incname = is_result-sobjname + RECEIVING + mtdkey = ls_mtdkey + EXCEPTIONS + class_not_existing = 1 + method_not_existing = 2 + OTHERS = 3 ). + IF sy-subrc = 0. + rv_txt = to_lower( |{ ls_mtdkey-clsname }->{ ls_mtdkey-cpdname }| ). + ELSE. + rv_txt = to_lower( |{ is_result-sobjname }| ). + ENDIF. + + ENDCASE. + CATCH cx_root. + " leave empty, fallback to default, defined elsewhere + ENDTRY. + + ENDMETHOD. + + + METHOD handle_navigation. + + DATA: ls_item TYPE zif_abapgit_definitions=>ty_item, + ls_sub_item TYPE zif_abapgit_definitions=>ty_item, + lv_main_object TYPE string, + lv_sub_object TYPE string, + lv_line_number_s TYPE string, + lv_line_number TYPE i. + + SPLIT iv_link AT c_object_separator INTO lv_main_object lv_sub_object lv_line_number_s. + ls_item-obj_type = to_upper( lv_main_object(4) ). + ls_item-obj_name = to_upper( lv_main_object+4(*) ). + + IF lv_sub_object IS NOT INITIAL. + ls_sub_item-obj_type = to_upper( lv_sub_object(4) ). + ls_sub_item-obj_name = to_upper( lv_sub_object+4(*) ). + ENDIF. + + lv_line_number = lv_line_number_s. + + jump( + is_item = ls_item + is_sub_item = ls_sub_item + iv_line_number = lv_line_number ). + + ENDMETHOD. + + METHOD jump. DATA: lo_test TYPE REF TO cl_ci_test_root, @@ -178,169 +365,249 @@ CLASS zcl_abapgit_gui_page_codi_base IMPLEMENTATION. METHOD on_event. - DATA: ls_item TYPE zif_abapgit_definitions=>ty_item, - ls_sub_item TYPE zif_abapgit_definitions=>ty_item, - lv_temp TYPE string, - lv_main_object TYPE string, - lv_sub_object TYPE string, - lv_line_number_s TYPE string, - lv_line_number TYPE i. + DATA lv_temp TYPE string. + DATA ls_sorting_req TYPE zif_abapgit_html_table=>ty_sorting_state. - lv_temp = replace( val = ii_event->mv_action - regex = |^{ c_ci_sig }| - with = `` ). + lv_temp = replace( + val = ii_event->mv_action + regex = |^{ c_ci_sig }| + with = `` ). IF lv_temp <> ii_event->mv_action. " CI navigation request detected - - SPLIT lv_temp AT c_object_separator INTO lv_main_object lv_sub_object lv_line_number_s. - ls_item-obj_type = to_upper( lv_main_object(4) ). - ls_item-obj_name = to_upper( lv_main_object+4(*) ). - - IF lv_sub_object IS NOT INITIAL. - ls_sub_item-obj_type = to_upper( lv_sub_object(4) ). - ls_sub_item-obj_name = to_upper( lv_sub_object+4(*) ). - ENDIF. - - lv_line_number = lv_line_number_s. - - jump( is_item = ls_item - is_sub_item = ls_sub_item - iv_line_number = lv_line_number ). - + handle_navigation( lv_temp ). rs_handled-state = zcl_abapgit_gui=>c_event_state-no_more_act. - ENDIF. - CASE ii_event->mv_action. + ls_sorting_req = zcl_abapgit_html_table=>detect_sorting_request( ii_event->mv_action ). + IF ls_sorting_req IS NOT INITIAL. + ms_sorting_state = ls_sorting_req. + rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. + ENDIF. - WHEN c_actions-sort_1. - SORT mt_result BY objtype objname test code sobjtype sobjname line col. - rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. - WHEN c_actions-sort_2. - SORT mt_result BY objtype objname sobjtype sobjname line col test code. - rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. - WHEN c_actions-sort_3. - SORT mt_result BY test code objtype objname sobjtype sobjname line col. - rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. - - ENDCASE. + IF ii_event->mv_action = c_actions-filter_kind. + mv_filter_kind = ii_event->query( )->get( 'kind' ). + rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. + ENDIF. ENDMETHOD. - METHOD render_result. + METHOD render_ci_report. - CONSTANTS: lc_limit TYPE i VALUE 500. - FIELD-SYMBOLS: LIKE LINE OF it_result. + ii_html->add( '
' ). - ii_html->add( '
' ). + render_head( + ii_html = ii_html + iv_variant = iv_variant + iv_summary = mv_summary ). - LOOP AT it_result ASSIGNING TO lc_limit. - render_result_line( - ii_html = ii_html - is_result = ). - ENDLOOP. + IF lines( mt_result ) = 0. + render_success( + ii_html = ii_html + iv_message = iv_success_msg ). + ELSE. + render_stats( + ii_html = ii_html + it_result = mt_result ). + render_detail( + ii_html = ii_html + it_result = mt_result ). + ENDIF. ii_html->add( '
' ). - IF lines( it_result ) > lc_limit. - ii_html->add( '
' ). - ii_html->add( ii_html->icon( 'exclamation-triangle' ) ). - ii_html->add( |Only first { lc_limit } findings shown in list!| ). - ii_html->add( '
' ). + ENDMETHOD. + + + METHOD render_detail. + + DATA li_table TYPE REF TO zcl_abapgit_html_table. + DATA lt_view TYPE ty_view_tab. + + li_table = zcl_abapgit_html_table=>create( + )->define_column( + iv_column_id = 'kind' + iv_column_title = zcl_abapgit_html=>icon( 'exclamation-circle' ) + )->define_column( + iv_column_id = 'obj_type' + iv_column_title = 'Type' + )->define_column( + iv_column_id = 'location' + iv_column_title = 'Obj. name / location' + )->define_column( + iv_column_id = 'text' + iv_column_title = 'Text' ). + + lt_view = convert_result_to_view( it_result ). + + IF ms_sorting_state-column_id IS INITIAL. + ms_sorting_state-column_id = 'kind'. + ENDIF. + + apply_sorting( CHANGING ct_view = lt_view ). + apply_filter_kind( CHANGING ct_view = lt_view ). + + ii_html->div( + iv_class = 'ci-detail' + ii_content = li_table->render( + ii_renderer = me + is_sorting_state = ms_sorting_state + iv_wrap_in_div = 'default-table-container' + iv_css_class = 'default-table' + iv_with_cids = abap_true + it_data = lt_view ) ). + + IF lines( it_result ) > c_limit. + render_limit_warning( ii_html ). ENDIF. ENDMETHOD. - METHOD render_result_line. + METHOD render_head. - DATA: lv_class TYPE string, - lv_obj_txt TYPE string, - lv_msg TYPE string, - lv_line TYPE i, - ls_mtdkey TYPE seocpdkey. + ii_html->div( + iv_class = 'ci-msg' + iv_content = + |Code inspector check variant { + iv_variant } completed ({ iv_summary })| ). - CASE is_result-kind. + ENDMETHOD. + + + METHOD render_limit_warning. + ii_html->add( '
' ). + ii_html->add( ii_html->icon( 'exclamation-triangle' ) ). + ii_html->add( |Only first { c_limit } findings shown in list!| ). + ii_html->add( '
' ). + ENDMETHOD. + + + METHOD render_stat. + + DATA lv_txt TYPE string. + + lv_txt = |{ iv_count } { iv_title }|. + + IF iv_type <> mv_filter_kind. + lv_txt = ii_html->a( + iv_txt = lv_txt + iv_act = |{ c_actions-filter_kind }?kind={ iv_type }| + iv_typ = zif_abapgit_html=>c_action_type-sapevent ). + ENDIF. + + ii_html->add( |{ lv_txt }| ). + + ENDMETHOD. + + + METHOD render_stats. + + FIELD-SYMBOLS LIKE LINE OF it_result. + + DATA lv_errors TYPE i. + DATA lv_warnings TYPE i. + DATA lv_infos TYPE i. + + IF mv_filter_kind IS INITIAL. + mv_filter_kind = 'all'. + ENDIF. + + LOOP AT it_result ASSIGNING . + CASE -kind. + WHEN 'E'. + lv_errors = lv_errors + 1. + WHEN 'W'. + lv_warnings = lv_warnings + 1. + WHEN OTHERS. + lv_infos = lv_infos + 1. + ENDCASE. + ENDLOOP. + + ii_html->add( '
' ). + + IF lv_errors > 0. + render_stat( + ii_html = ii_html + iv_count = lv_errors + iv_type = 'error' + iv_title = 'errors' ). + ENDIF. + IF lv_warnings > 0. + render_stat( + ii_html = ii_html + iv_count = lv_warnings + iv_type = 'warn' + iv_title = 'warnings' ). + ENDIF. + IF lv_infos > 0. + render_stat( + ii_html = ii_html + iv_count = lv_infos + iv_type = 'info' + iv_title = 'infos' ). + ENDIF. + render_stat( + ii_html = ii_html + iv_count = lv_infos + lv_errors + lv_warnings + iv_type = 'all' + iv_title = 'all' ). + + ii_html->add( '
' ). + + ENDMETHOD. + + + METHOD render_success. + + ii_html->add( '
' ). + ii_html->add( ii_html->icon( 'check' ) ). + ii_html->add( iv_message ). + ii_html->add( '
' ). + + ENDMETHOD. + + + METHOD zif_abapgit_html_table~get_row_attrs. + + FIELD-SYMBOLS TYPE ty_result_view. + + ASSIGN is_row TO . + rs_attrs-data-name = 'kind'. + + CASE -kind. WHEN 'E'. - lv_class = 'ci-error'. + rs_attrs-data-value = 'error'. WHEN 'W'. - lv_class = 'ci-warning'. + rs_attrs-data-value = 'warning'. WHEN OTHERS. - lv_class = 'ci-info'. + rs_attrs-data-value = 'info'. ENDCASE. - lv_msg = escape( val = is_result-text - format = cl_abap_format=>e_html_attr ). - - IF is_result-sobjname IS INITIAL OR - ( is_result-sobjname = is_result-objname AND - is_result-sobjtype = is_result-objtype ). - lv_obj_txt = |{ is_result-objtype } { is_result-objname }|. - ELSEIF is_result-objtype = 'CLAS' OR - ( is_result-objtype = 'PROG' AND NOT is_result-sobjname+30(*) IS INITIAL ). - TRY. - CASE is_result-sobjname+30(*). - WHEN 'CCDEF'. - lv_obj_txt = |CLAS { is_result-objname } : Local Definitions|. - WHEN 'CCIMP'. - lv_obj_txt = |CLAS { is_result-objname } : Local Implementations|. - WHEN 'CCMAC'. - lv_obj_txt = |CLAS { is_result-objname } : Macros|. - WHEN 'CCAU'. - lv_obj_txt = |CLAS { is_result-objname } : Test Classes|. - WHEN 'CU'. - lv_obj_txt = |CLAS { is_result-objname } : Public Section|. - WHEN 'CO'. - lv_obj_txt = |CLAS { is_result-objname } : Protected Section|. - WHEN 'CI'. - lv_obj_txt = |CLAS { is_result-objname } : Private Section|. - WHEN OTHERS. - cl_oo_classname_service=>get_method_by_include( - EXPORTING - incname = is_result-sobjname - RECEIVING - mtdkey = ls_mtdkey - EXCEPTIONS - class_not_existing = 1 - method_not_existing = 2 - OTHERS = 3 ). - IF sy-subrc = 0. - lv_obj_txt = |CLAS { ls_mtdkey-clsname }->{ ls_mtdkey-cpdname }|. - ELSE. - lv_obj_txt = |{ is_result-objtype } { is_result-sobjname }|. - ENDIF. - - ENDCASE. - CATCH cx_root. - lv_obj_txt = ''. "use default below - ENDTRY. - ENDIF. - IF lv_obj_txt IS INITIAL. - lv_obj_txt = |{ is_result-objtype } { is_result-objname } > { is_result-sobjtype } { is_result-sobjname }|. - ENDIF. - lv_line = is_result-line. " convert from numc to integer - lv_obj_txt = |{ lv_obj_txt } [ @{ lv_line } ]|. - - ii_html->add( |
  • | ). - ii_html->add_a( - iv_txt = lv_obj_txt - iv_act = build_nav_link( is_result ) - iv_typ = zif_abapgit_html=>c_action_type-sapevent ). - ii_html->add( |{ lv_msg }| ). - ii_html->add( '
  • ' ). - ENDMETHOD. - METHOD render_variant. + METHOD zif_abapgit_html_table~render_cell. - CREATE OBJECT ri_html TYPE zcl_abapgit_html. + FIELD-SYMBOLS TYPE ty_result_view. - ri_html->add( '
    ' ). - ri_html->add( |Code inspector check variant { iv_variant }| - && | completed ({ iv_summary })| ). - ri_html->add( `
    ` ). + ASSIGN is_row TO . + + CASE iv_column_id. + WHEN 'kind'. + rs_render-content = |{ -kind }|. + WHEN 'obj_type'. + rs_render-content = -obj_type. + WHEN 'location'. + rs_render-content = zcl_abapgit_html=>create( )->a( + iv_txt = -location + iv_act = -nav + iv_typ = zif_abapgit_html=>c_action_type-sapevent ). + WHEN 'text'. + rs_render-content = escape( + val = -text + format = cl_abap_format=>e_html_attr ). + ENDCASE. ENDMETHOD. ENDCLASS. diff --git a/src/ui/pages/codi/zcl_abapgit_gui_page_syntax.clas.abap b/src/ui/pages/codi/zcl_abapgit_gui_page_syntax.clas.abap index 0d100b6b1..5b84eb3c1 100644 --- a/src/ui/pages/codi/zcl_abapgit_gui_page_syntax.clas.abap +++ b/src/ui/pages/codi/zcl_abapgit_gui_page_syntax.clas.abap @@ -7,6 +7,7 @@ CLASS zcl_abapgit_gui_page_syntax DEFINITION PUBLIC SECTION. INTERFACES: + zif_abapgit_gui_page_title, zif_abapgit_gui_event_handler, zif_abapgit_gui_hotkeys, zif_abapgit_gui_menu_provider, @@ -20,12 +21,11 @@ CLASS zcl_abapgit_gui_page_syntax DEFINITION RAISING zcx_abapgit_exception. - METHODS: - constructor - IMPORTING - io_repo TYPE REF TO zcl_abapgit_repo - RAISING - zcx_abapgit_exception. + METHODS constructor + IMPORTING + io_repo TYPE REF TO zcl_abapgit_repo + RAISING + zcx_abapgit_exception. PROTECTED SECTION. @@ -33,16 +33,15 @@ CLASS zcl_abapgit_gui_page_syntax DEFINITION PRIVATE SECTION. - METHODS: - run_syntax_check - RAISING - zcx_abapgit_exception. + METHODS run_syntax_check + RAISING + zcx_abapgit_exception. ENDCLASS. -CLASS zcl_abapgit_gui_page_syntax IMPLEMENTATION. +CLASS ZCL_ABAPGIT_GUI_PAGE_SYNTAX IMPLEMENTATION. METHOD constructor. @@ -60,10 +59,7 @@ CLASS zcl_abapgit_gui_page_syntax IMPLEMENTATION. EXPORTING io_repo = io_repo. - ri_page = zcl_abapgit_gui_page_hoc=>create( - iv_page_title = 'Syntax Check' - ii_page_menu_provider = lo_component - ii_child_component = lo_component ). + ri_page = zcl_abapgit_gui_page_hoc=>create( lo_component ). ENDMETHOD. @@ -126,32 +122,27 @@ CLASS zcl_abapgit_gui_page_syntax IMPLEMENTATION. ENDMETHOD. + METHOD zif_abapgit_gui_page_title~get_page_title. + rv_title = 'Syntax Check'. + ENDMETHOD. + + METHOD zif_abapgit_gui_renderable~render. register_handlers( ). 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 ) ). - ri_html->add( `
    ` ). + ri_html->div( + iv_class = 'repo' + ii_content = zcl_abapgit_gui_chunk_lib=>render_repo_top( + io_repo = mo_repo + iv_show_commit = abap_false ) ). - ri_html->add( '
    ' ). - - ri_html->add( render_variant( + render_ci_report( + ii_html = ri_html iv_variant = c_variant - iv_summary = mv_summary ) ). - - IF lines( mt_result ) = 0. - ri_html->add( '
    ' ). - ri_html->add( ri_html->icon( 'check' ) ). - ri_html->add( 'No syntax errors' ). - ri_html->add( '
    ' ). - ELSE. - render_result( ii_html = ri_html - it_result = mt_result ). - ENDIF. + iv_success_msg = 'No syntax errors' ). ENDMETHOD. ENDCLASS. diff --git a/src/ui/pages/zcl_abapgit_gui_page_stage.clas.abap b/src/ui/pages/zcl_abapgit_gui_page_stage.clas.abap index c9a67bce4..ecc824046 100644 --- a/src/ui/pages/zcl_abapgit_gui_page_stage.clas.abap +++ b/src/ui/pages/zcl_abapgit_gui_page_stage.clas.abap @@ -25,6 +25,7 @@ CLASS zcl_abapgit_gui_page_stage DEFINITION iv_seed TYPE string OPTIONAL iv_sci_result TYPE zif_abapgit_definitions=>ty_sci_result DEFAULT zif_abapgit_definitions=>c_sci_result-no_run ii_obj_filter TYPE REF TO zif_abapgit_object_filter OPTIONAL + ii_force_refresh TYPE abap_bool DEFAULT abap_true RETURNING VALUE(ri_page) TYPE REF TO zif_abapgit_gui_renderable RAISING @@ -36,6 +37,7 @@ CLASS zcl_abapgit_gui_page_stage DEFINITION iv_seed TYPE string OPTIONAL iv_sci_result TYPE zif_abapgit_definitions=>ty_sci_result DEFAULT zif_abapgit_definitions=>c_sci_result-no_run ii_obj_filter TYPE REF TO zif_abapgit_object_filter OPTIONAL + ii_force_refresh TYPE abap_bool DEFAULT abap_true RAISING zcx_abapgit_exception. @@ -135,7 +137,7 @@ ENDCLASS. -CLASS zcl_abapgit_gui_page_stage IMPLEMENTATION. +CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION. METHOD check_selected. @@ -184,6 +186,11 @@ CLASS zcl_abapgit_gui_page_stage IMPLEMENTATION. super->constructor( ). + " force refresh on stage, to make sure the latest local and remote files are used + IF ii_force_refresh = abap_true. + io_repo->refresh( ). + ENDIF. + mo_repo = io_repo. mv_seed = iv_seed. mv_sci_result = iv_sci_result. @@ -231,6 +238,7 @@ CLASS zcl_abapgit_gui_page_stage IMPLEMENTATION. io_repo = io_repo iv_seed = iv_seed iv_sci_result = iv_sci_result + ii_force_refresh = ii_force_refresh ii_obj_filter = ii_obj_filter. ri_page = zcl_abapgit_gui_page_hoc=>create( diff --git a/src/ui/routing/zcl_abapgit_gui_router.clas.abap b/src/ui/routing/zcl_abapgit_gui_router.clas.abap index 83bf55134..d9d36f968 100644 --- a/src/ui/routing/zcl_abapgit_gui_router.clas.abap +++ b/src/ui/routing/zcl_abapgit_gui_router.clas.abap @@ -142,7 +142,7 @@ ENDCLASS. -CLASS zcl_abapgit_gui_router IMPLEMENTATION. +CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION. METHOD abapgit_services_actions. @@ -402,9 +402,6 @@ CLASS zcl_abapgit_gui_router IMPLEMENTATION. ENDIF. IF ri_page IS INITIAL. - " force refresh on stage, to make sure the latest local and remote files are used - lo_repo->refresh( ). - ri_page = zcl_abapgit_gui_page_stage=>create( io_repo = lo_repo iv_seed = lv_seed diff --git a/src/ui/zabapgit_css_common.w3mi.data.css b/src/ui/zabapgit_css_common.w3mi.data.css index c955b9a8a..8d6c205e9 100644 --- a/src/ui/zabapgit_css_common.w3mi.data.css +++ b/src/ui/zabapgit_css_common.w3mi.data.css @@ -1183,23 +1183,100 @@ table ul.repo-labels li { word-wrap: break-word; } +/* TABLE COMPONENT DEFAULT STYLE */ + +div.default-table-container { + padding: 6px 0.5em; + background-color: white; + border-radius: 6px; +} + +table.default-table { + line-height: 1.5; + width: 100%; +} + +table.default-table thead tr { + border-bottom: #efefef solid 1px; +} +/*table.default-table tbody tr { + border-bottom: #efefef solid 1px; +} +table.default-table tbody tr:last-child { + border-bottom: none; +}*/ + +table.default-table td, +table.default-table th { + padding: 6px 8px; + text-align: left; +} + +table.default-table th span.sort-arrow { + display: inline-block; + color: hsla(0, 0%, 0%, 0.15); + width: 1em; /*for constant width*/ + text-align: right; +} + +table.default-table th span.sort-active { + color: #4078c0; +} + +table.default-table th { + padding-bottom: 10px; +} + /* CODE INSPECTOR */ -.ci-head { padding: 0.5em 1em; } -.ci-head .package-name span { margin-left: 0.3em; } -.ci-variant { font-weight: bold; } -.ci-result { - padding: 6px; - margin-top: 4px; +div.ci { + margin-top: 1px; + margin-bottom: 1px; } -.ci-result li { - list-style-type: none; - padding: 0.3em 0.8em; - margin-top: 6px; - border-left: 4px solid; + +div.ci-msg { + padding: 0.7em 1em 0.5em; +} +div.ci-msg span.ci-variant { + font-weight: bold; +} + +div.ci-stats { + padding: 0.5em 1em; +} +div.ci-stats span.count { + display: inline-block; + padding: 2px 6px; + border-radius: 3px; + border: 1px solid; +} + +div.ci-detail { + padding: 6px 0.5em; +} + +div.ci-detail table td, +div.ci-detail table th { + vertical-align: text-top; +} + +div.ci-detail table th[data-cid="kind"], +div.ci-detail table th[data-cid="obj_type"] { + white-space: nowrap +} + +div.ci-detail table td[data-cid="kind"] span { + display: inline-block; + border-radius: 3px; + width: 1em; + height: 1em; + vertical-align: inherit; + color: transparent; +} + +div.ci-detail table td[data-cid="text"] { + font-size: smaller; } -.ci-result li:first-child { margin-top: 0px; } -.ci-result li > span { display: block; } /* FLOATING BUTTONS */ diff --git a/src/ui/zabapgit_css_theme_default.w3mi.data.css b/src/ui/zabapgit_css_theme_default.w3mi.data.css index 3e90bf48c..2a369aedd 100644 --- a/src/ui/zabapgit_css_theme_default.w3mi.data.css +++ b/src/ui/zabapgit_css_theme_default.w3mi.data.css @@ -405,14 +405,39 @@ div.corner-hint { /* CODE INSPECTOR */ -.ci-head { background-color: var(--theme-container-background-color); } -.ci-head .package-name span { color: grey; } -.ci-variant { color: #444; } -.ci-result { background-color: #f6f6f6; } -.ci-result li { color: #444; } -.ci-result li.ci-error { border-left-color: #cd5353; } -.ci-result li.ci-warning { border-left-color: #ecd227; } -.ci-result li.ci-info { border-left-color: #acacac; } +div.ci { background-color: var(--theme-container-background-color); } + +div.ci-msg span.ci-variant { color: var(--theme-primary-font-color); } + +div.ci-stats span.error-count { + border-color: hsl(350, 100%, 80%); + background-color: hsl(350, 100%, 90%); +} +div.ci-stats span.warn-count { + border-color: hsl(60, 100%, 42%); + background-color: hsl(60, 100%, 90%); +} +div.ci-stats span.info-count { + border-color: hsl(120, 80%, 80%); + background-color: hsl(120, 80%, 94%); +} +div.ci-stats span.all-count { + border-color: hsl(235, 100%, 89%); + background-color: hsl(235, 100%, 93%); +} +div.ci-detail table td[data-cid="text"] { + color: hsl(0, 0%, 40%); +} + +div.ci-detail table tr[data-kind="error"] td[data-cid="kind"] span { + background-color: hsl(0, 100%, 68%); +} +div.ci-detail table tr[data-kind="warning"] td[data-cid="kind"] span { + background-color:hsl(52, 100%, 49%); +} +div.ci-detail table tr[data-kind="info"] td[data-cid="kind"] span { + background-color: hsl(118, 67%, 47%); +} /* COMMAND PALETTE */