From 450c7c76343e1a7509d7dd459faf2b47ef9a0f8b Mon Sep 17 00:00:00 2001 From: larshp Date: Sat, 18 Feb 2017 14:41:39 +0000 Subject: [PATCH 01/28] Function groups, #305 testing, the solution is not perfect as it looks like there are diffs for VARCL, but at least the syntax error is fixed --- src/zabapgit_object_fugr.prog.abap | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/zabapgit_object_fugr.prog.abap b/src/zabapgit_object_fugr.prog.abap index ffd9d82d6..750976cc8 100644 --- a/src/zabapgit_object_fugr.prog.abap +++ b/src/zabapgit_object_fugr.prog.abap @@ -448,6 +448,9 @@ CLASS lcl_object_fugr IMPLEMENTATION. DELETE TABLE rt_includes FROM -include. ENDLOOP. +* handle generated maintenance views + APPEND INITIAL LINE TO rt_includes ASSIGNING . + = |L{ ms_item-obj_name }T00|. LOOP AT rt_includes ASSIGNING . lv_tabix = sy-tabix. @@ -469,7 +472,6 @@ CLASS lcl_object_fugr IMPLEMENTATION. IF sy-subrc <> 0. DELETE rt_includes INDEX lv_tabix. ENDIF. - ENDLOOP. APPEND lv_program TO rt_includes. From 611efe018beef8a8d5990dbfd2af156f488ec576 Mon Sep 17 00:00:00 2001 From: larshp Date: Sun, 19 Feb 2017 08:16:02 +0000 Subject: [PATCH 02/28] Switch to Branch with long Name results in shortdu #631 this is a workaround, code could be better --- src/zabapgit_popups.prog.abap | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/zabapgit_popups.prog.abap b/src/zabapgit_popups.prog.abap index acf62a0b3..01df95df0 100644 --- a/src/zabapgit_popups.prog.abap +++ b/src/zabapgit_popups.prog.abap @@ -390,7 +390,13 @@ CLASS lcl_popups IMPLEMENTATION. ELSE. REPLACE FIRST OCCURRENCE OF lv_head_suffix IN -varoption WITH ''. READ TABLE lt_branches WITH KEY display_name = -varoption ASSIGNING . - ASSERT sy-subrc = 0. + IF sy-subrc <> 0. +* branch name longer than 65 characters + LOOP AT lt_branches ASSIGNING WHERE display_name CS -varoption. + EXIT. " current loop + ENDLOOP. + ENDIF. + ASSERT IS ASSIGNED. rs_branch = lo_branches->find_by_name( -name ). ENDIF. From fd468a2b77e8662455c6a7c224c840ac0a7d5abe Mon Sep 17 00:00:00 2001 From: larshp Date: Sun, 19 Feb 2017 10:22:54 +0000 Subject: [PATCH 03/28] SFPI support #99 --- src/zabapgit_object_serializing.prog.abap | 1 + src/zabapgit_object_sfpi.prog.abap | 168 ++++++++++++++++++++++ src/zabapgit_object_sfpi.prog.xml | 22 +++ src/zabapgit_object_ssfo.prog.abap | 4 +- src/zabapgit_xml.prog.abap | 4 +- 5 files changed, 195 insertions(+), 4 deletions(-) create mode 100644 src/zabapgit_object_sfpi.prog.abap create mode 100644 src/zabapgit_object_sfpi.prog.xml diff --git a/src/zabapgit_object_serializing.prog.abap b/src/zabapgit_object_serializing.prog.abap index 4e34ba17e..33ad3c7e9 100644 --- a/src/zabapgit_object_serializing.prog.abap +++ b/src/zabapgit_object_serializing.prog.abap @@ -29,6 +29,7 @@ INCLUDE zabapgit_object_pinf. INCLUDE zabapgit_object_prog. INCLUDE zabapgit_object_sfbf. INCLUDE zabapgit_object_sfbs. +INCLUDE zabapgit_object_sfpi. INCLUDE zabapgit_object_sfsw. INCLUDE zabapgit_object_shi3. INCLUDE zabapgit_object_shlp. diff --git a/src/zabapgit_object_sfpi.prog.abap b/src/zabapgit_object_sfpi.prog.abap new file mode 100644 index 000000000..67234e8cf --- /dev/null +++ b/src/zabapgit_object_sfpi.prog.abap @@ -0,0 +1,168 @@ +*&---------------------------------------------------------------------* +*& Include ZABAPGIT_OBJECT_DOMA +*&---------------------------------------------------------------------* + +*----------------------------------------------------------------------* +* CLASS lcl_object_doma DEFINITION +*----------------------------------------------------------------------* +* +*----------------------------------------------------------------------* +CLASS lcl_object_sfpi DEFINITION INHERITING FROM lcl_objects_super FINAL. + + PUBLIC SECTION. + INTERFACES lif_object. + ALIASES mo_files FOR lif_object~mo_files. + + PRIVATE SECTION. + METHODS: + load + RETURNING VALUE(ri_wb_interface) TYPE REF TO if_fp_wb_interface + RAISING lcx_exception, + interface_to_xstring + RETURNING VALUE(rv_xstr) TYPE xstring + RAISING lcx_exception. + +ENDCLASS. "lcl_object_doma DEFINITION + +*----------------------------------------------------------------------* +* CLASS lcl_object_doma IMPLEMENTATION +*----------------------------------------------------------------------* +* +*----------------------------------------------------------------------* +CLASS lcl_object_sfpi IMPLEMENTATION. + + METHOD lif_object~has_changed_since. + rv_changed = abap_true. + ENDMETHOD. "lif_object~has_changed_since + + METHOD lif_object~changed_by. + + SELECT SINGLE lastuser FROM fpinterface + INTO rv_user + WHERE name = ms_item-obj_name + AND state = 'A'. + IF rv_user IS INITIAL. + SELECT SINGLE firstuser FROM fpinterface + INTO rv_user + WHERE name = ms_item-obj_name + AND state = 'A'. + ENDIF. + IF rv_user IS INITIAL. + rv_user = c_user_unknown. + ENDIF. + + ENDMETHOD. + + METHOD lif_object~get_metadata. + rs_metadata = get_metadata( ). + ENDMETHOD. "lif_object~get_metadata + + METHOD lif_object~exists. + + DATA: lv_name TYPE fpinterface-name. + + SELECT SINGLE name FROM fpinterface + INTO lv_name + WHERE name = ms_item-obj_name + AND state = 'A'. + rv_bool = boolc( sy-subrc = 0 ). + + ENDMETHOD. "lif_object~exists + + METHOD lif_object~jump. + lcx_exception=>raise( 'todo, SFPI jump' ). + ENDMETHOD. "jump + + METHOD lif_object~delete. + + DATA: lv_name TYPE fpname, + lo_wb_interface TYPE REF TO cl_fp_wb_interface. + + + lo_wb_interface ?= load( ). + + lv_name = ms_item-obj_name. + + TRY. + lo_wb_interface->delete( lv_name ). + CATCH cx_fp_api. + lcx_exception=>raise( 'SFPI error, delete' ). + ENDTRY. + + ENDMETHOD. "delete + + METHOD load. + + DATA: lv_name TYPE fpname. + + + lv_name = ms_item-obj_name. + + TRY. + ri_wb_interface = cl_fp_wb_interface=>load( lv_name ). + CATCH cx_fp_api. + lcx_exception=>raise( 'SFPI error, load' ). + ENDTRY. + + ENDMETHOD. + + METHOD interface_to_xstring. + + DATA: lv_xstr TYPE xstring, + li_fp_interface TYPE REF TO if_fp_interface, + li_wb_interface TYPE REF TO if_fp_wb_interface. + + + TRY. + li_wb_interface = load( ). + li_fp_interface ?= li_wb_interface->get_object( ). + rv_xstr = cl_fp_helper=>convert_interface_to_xstring( li_fp_interface ). + CATCH cx_fp_api. + lcx_exception=>raise( 'SFPI error, interface_to_xstring' ). + ENDTRY. + + ENDMETHOD. + + METHOD lif_object~serialize. + + DATA: lv_xstr TYPE xstring, + li_document TYPE REF TO if_ixml_document. + + + lv_xstr = interface_to_xstring( ). + li_document = cl_ixml_80_20=>parse_to_document( stream_xstring = lv_xstr ). + io_xml->set_raw( li_document->get_root_element( ) ). + + ENDMETHOD. "serialize + + METHOD lif_object~deserialize. + + DATA: lv_xstr TYPE xstring, + lv_name TYPE fpname, + li_wb_object TYPE REF TO if_fp_wb_interface, + li_interface TYPE REF TO if_fp_interface. + + + lv_name = ms_item-obj_name. + lv_xstr = cl_ixml_80_20=>render_to_xstring( io_xml->get_raw( ) ). + + TRY. + li_interface = cl_fp_helper=>convert_xstring_to_interface( lv_xstr ). + tadir_insert( iv_package ). + li_wb_object = cl_fp_wb_interface=>create( i_name = lv_name + i_interface = li_interface ). + li_wb_object->save( ). + li_wb_object->free( ). + CATCH cx_fp_api. + lcx_exception=>raise( 'SFPI error, deserialize' ). + ENDTRY. + + lcl_objects_activation=>add_item( ms_item ). + + ENDMETHOD. "deserialize + + METHOD lif_object~compare_to_remote_version. + CREATE OBJECT ro_comparison_result TYPE lcl_null_comparison_result. + ENDMETHOD. + +ENDCLASS. "lcl_object_doma IMPLEMENTATION diff --git a/src/zabapgit_object_sfpi.prog.xml b/src/zabapgit_object_sfpi.prog.xml new file mode 100644 index 000000000..15fde47e5 --- /dev/null +++ b/src/zabapgit_object_sfpi.prog.xml @@ -0,0 +1,22 @@ + + + + + + ZABAPGIT_OBJECT_SFPI + A + X + I + E + X + + + + R + Include ZABAPGIT_OBJECT_DOMA + 28 + + + + + diff --git a/src/zabapgit_object_ssfo.prog.abap b/src/zabapgit_object_ssfo.prog.abap index ff7ceb1f7..671881b61 100644 --- a/src/zabapgit_object_ssfo.prog.abap +++ b/src/zabapgit_object_ssfo.prog.abap @@ -200,7 +200,7 @@ CLASS lcl_object_ssfo IMPLEMENTATION. CREATE OBJECT lo_sf. * set "created by" and "changed by" to current user - li_iterator = io_xml->get_raw( )->create_iterator( ). + li_iterator = io_xml->get_raw( )->get_root_element( )->create_iterator( ). li_node = li_iterator->get_next( ). WHILE NOT li_node IS INITIAL. lv_name = li_node->get_name( ). @@ -226,7 +226,7 @@ CLASS lcl_object_ssfo IMPLEMENTATION. mode = 'INSERT' formname = lv_formname ). - lo_sf->xml_upload( EXPORTING dom = io_xml->get_raw( ) + lo_sf->xml_upload( EXPORTING dom = io_xml->get_raw( )->get_root_element( ) formname = lv_formname language = mv_language CHANGING sform = lo_res ). diff --git a/src/zabapgit_xml.prog.abap b/src/zabapgit_xml.prog.abap index 9bf5db1dd..edcd55efc 100644 --- a/src/zabapgit_xml.prog.abap +++ b/src/zabapgit_xml.prog.abap @@ -294,7 +294,7 @@ CLASS lcl_xml_input DEFINITION FINAL INHERITING FROM lcl_xml CREATE PUBLIC. CHANGING cg_data TYPE any RAISING lcx_exception, get_raw - RETURNING VALUE(ri_raw) TYPE REF TO if_ixml_node, + RETURNING VALUE(ri_raw) TYPE REF TO if_ixml_document, * todo, add read_xml to match add_xml in lcl_xml_output get_metadata RETURNING VALUE(rs_metadata) TYPE ty_metadata. @@ -320,7 +320,7 @@ CLASS lcl_xml_input IMPLEMENTATION. ENDMETHOD. "constructor METHOD get_raw. - ri_raw = mi_xml_doc->get_root_element( ). + ri_raw = mi_xml_doc. ENDMETHOD. "get_raw METHOD fix_xml. From f2d14670190b54334ee106b369e2162b8e0de957 Mon Sep 17 00:00:00 2001 From: larshp Date: Sun, 19 Feb 2017 11:20:05 +0000 Subject: [PATCH 04/28] SFPI: fix oref XML attributes --- src/zabapgit_object_sfpi.prog.abap | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/zabapgit_object_sfpi.prog.abap b/src/zabapgit_object_sfpi.prog.abap index 67234e8cf..930151f6d 100644 --- a/src/zabapgit_object_sfpi.prog.abap +++ b/src/zabapgit_object_sfpi.prog.abap @@ -18,6 +18,8 @@ CLASS lcl_object_sfpi DEFINITION INHERITING FROM lcl_objects_super FINAL. load RETURNING VALUE(ri_wb_interface) TYPE REF TO if_fp_wb_interface RAISING lcx_exception, + fix_oref + IMPORTING ii_document TYPE REF TO if_ixml_document, interface_to_xstring RETURNING VALUE(rv_xstr) TYPE xstring RAISING lcx_exception. @@ -123,6 +125,58 @@ CLASS lcl_object_sfpi IMPLEMENTATION. ENDMETHOD. + METHOD fix_oref. + + DATA: li_iterator TYPE REF TO if_ixml_node_iterator, + lv_name TYPE string, + lv_value TYPE string, + lv_new TYPE n LENGTH 3, + lv_old TYPE string, + lt_map TYPE STANDARD TABLE OF string WITH DEFAULT KEY, + li_attr_map TYPE REF TO if_ixml_named_node_map, + li_attr TYPE REF TO if_ixml_node, + li_node TYPE REF TO if_ixml_node. + + DEFINE _lookup. + read table lt_map from &1 transporting no fields. + if sy-subrc <> 0. + append &1 to lt_map. + read table lt_map from &1 transporting no fields. + endif. + lv_new = sy-tabix + 100. + END-OF-DEFINITION. + + + li_iterator = ii_document->create_iterator( ). + li_node = li_iterator->get_next( ). + WHILE NOT li_node IS INITIAL. + li_attr_map = li_node->get_attributes( ). + + IF li_attr_map IS BOUND. + li_attr = li_attr_map->get_named_item_ns( 'href' ). + IF li_attr IS BOUND. + lv_old = li_attr->get_value( ). + IF lv_old(2) = '#o'. + _lookup lv_old+1. + li_attr->set_value( '#o' && lv_new ). + ENDIF. + ENDIF. + + li_attr = li_attr_map->get_named_item_ns( 'id' ). + IF li_attr IS BOUND. + lv_old = li_attr->get_value( ). + IF lv_old(1) = 'o'. + _lookup lv_old. + li_attr->set_value( 'o' && lv_new ). + ENDIF. + ENDIF. + ENDIF. + + li_node = li_iterator->get_next( ). + ENDWHILE. + + ENDMETHOD. + METHOD lif_object~serialize. DATA: lv_xstr TYPE xstring, @@ -131,6 +185,7 @@ CLASS lcl_object_sfpi IMPLEMENTATION. lv_xstr = interface_to_xstring( ). li_document = cl_ixml_80_20=>parse_to_document( stream_xstring = lv_xstr ). + fix_oref( li_document ). io_xml->set_raw( li_document->get_root_element( ) ). ENDMETHOD. "serialize From 929ab2449e4794988f5964a07c249d31ef028ff0 Mon Sep 17 00:00:00 2001 From: larshp Date: Wed, 22 Feb 2017 16:16:09 +0000 Subject: [PATCH 05/28] v1.30.0 SFPI support * fix for generated maintenance function groups * fix for long branch names in popup --- src/zabapgit.prog.abap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zabapgit.prog.abap b/src/zabapgit.prog.abap index 12344e828..4d2441127 100644 --- a/src/zabapgit.prog.abap +++ b/src/zabapgit.prog.abap @@ -3,7 +3,7 @@ REPORT zabapgit LINE-SIZE 100. * See http://www.abapgit.org CONSTANTS: gc_xml_version TYPE string VALUE 'v1.0.0', "#EC NOTEXT - gc_abap_version TYPE string VALUE 'v1.29.0'. "#EC NOTEXT + gc_abap_version TYPE string VALUE 'v1.30.0'. "#EC NOTEXT ******************************************************************************** * The MIT License (MIT) From 0f7721d2d50ab58781fcbc9d10f5aa2d7b956d1b Mon Sep 17 00:00:00 2001 From: Lars Hvam Date: Wed, 22 Feb 2017 17:25:18 +0100 Subject: [PATCH 06/28] v1.30.0 --- changelog.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/changelog.txt b/changelog.txt index f40cb2411..f778b4ec6 100644 --- a/changelog.txt +++ b/changelog.txt @@ -8,6 +8,18 @@ Legend + : added - : removed +2017-02-22 v1.30.0 +------------------ ++ SFPI support +* fix for long branch names in popup +* fix for generated maintenance function groups +* changes to staging screen +* should show less package popups during pull + +2017-02-17 v1.29.0 +------------------ ++ FULL folder logic added + 2017-02-13 v1.28.0 ------------------ + Staging page redesigned From ca91c2237165dfaec926e1cdd45c7a10267174af Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Wed, 22 Feb 2017 19:36:09 +0200 Subject: [PATCH 07/28] separate login, author and committer #535 committer - double m, double t ;) --- src/zabapgit_background.prog.abap | 14 +-- src/zabapgit_css_common.w3mi.data.css | 22 ++++- src/zabapgit_definitions.prog.abap | 17 +++- src/zabapgit_git.prog.abap | 12 ++- src/zabapgit_html_action_utils.prog.abap | 11 ++- src/zabapgit_http.prog.abap | 6 +- src/zabapgit_page_commit.prog.abap | 102 +++++++++++++-------- src/zabapgit_persistence.prog.abap | 112 ++++++++++++++--------- src/zabapgit_services_git.prog.abap | 38 ++++---- 9 files changed, 212 insertions(+), 122 deletions(-) diff --git a/src/zabapgit_background.prog.abap b/src/zabapgit_background.prog.abap index 1b3368c04..9cfa072b2 100644 --- a/src/zabapgit_background.prog.abap +++ b/src/zabapgit_background.prog.abap @@ -75,9 +75,9 @@ CLASS lcl_background IMPLEMENTATION. iv_data = -file-data ). ENDLOOP. - ls_comment-username = is_settings-aname. - ls_comment-email = is_settings-amail. - ls_comment-comment = build_comment( ls_files ). + ls_comment-committer-name = is_settings-aname. + ls_comment-committer-email = is_settings-amail. + ls_comment-comment = build_comment( ls_files ). io_repo->push( is_comment = ls_comment io_stage = lo_stage ). @@ -131,8 +131,8 @@ CLASS lcl_background IMPLEMENTATION. ENDIF. CLEAR ls_comment. - ls_comment-username = lcl_objects=>changed_by( -item ). - ls_comment-email = |{ ls_comment-username }@localhost|. + ls_comment-committer-name = lcl_objects=>changed_by( -item ). + ls_comment-committer-email = |{ ls_comment-committer-name }@localhost|. CREATE OBJECT lo_stage EXPORTING @@ -142,9 +142,9 @@ CLASS lcl_background IMPLEMENTATION. CLEAR ls_user_files. LOOP AT ls_files-local ASSIGNING . - IF lcl_objects=>changed_by( -item ) = ls_comment-username. + IF lcl_objects=>changed_by( -item ) = ls_comment-committer-name. WRITE: / 'stage' ##NO_TEXT, - ls_comment-username, + ls_comment-committer-name, -file-path, -file-filename. diff --git a/src/zabapgit_css_common.w3mi.data.css b/src/zabapgit_css_common.w3mi.data.css index 4ab352f62..31365ec0b 100644 --- a/src/zabapgit_css_common.w3mi.data.css +++ b/src/zabapgit_css_common.w3mi.data.css @@ -408,17 +408,35 @@ input.stage-filter { width: 18em; } } /* COMMIT */ -div.form_div { +div.form-container { margin: 0.5em 0em; background-color: #F8F8F8; padding: 1em 1em; } -div.form_div td.field_name { +form.aligned-form { + display: table; + border-spacing: 2px; +} + +form.aligned-form label { color: #BBB; padding-right: 1em; + vertical-align: middle; } +form.aligned-form span.sub-title { + color: #BBB; + font-size: smaller; + padding-top: 8px; +} + +form.aligned-form div.row { display: table-row; } +form.aligned-form label { display: table-cell; } +form.aligned-form input { display: table-cell; } +form.aligned-form input[type="text"] { width: 25em; } +form.aligned-form span.cell { display: table-cell; } + /* SETTINGS STYLES */ div.settings_container { padding: 0.5em; diff --git a/src/zabapgit_definitions.prog.abap b/src/zabapgit_definitions.prog.abap index 30a6e3e40..a1edf8f5d 100644 --- a/src/zabapgit_definitions.prog.abap +++ b/src/zabapgit_definitions.prog.abap @@ -28,11 +28,18 @@ TYPES: ty_files_tt TYPE STANDARD TABLE OF ty_file WITH DEFAULT KEY. TYPES: ty_string_tt TYPE STANDARD TABLE OF string WITH DEFAULT KEY. -TYPES: BEGIN OF ty_comment, - username TYPE string, - email TYPE string, - comment TYPE string, - END OF ty_comment. +TYPES: + BEGIN OF ty_git_user, + name TYPE string, + email TYPE string, + END OF ty_git_user. + +TYPES: + BEGIN OF ty_comment, + committer TYPE ty_git_user, + author TYPE ty_git_user, + comment TYPE string, + END OF ty_comment. TYPES: BEGIN OF ty_item, obj_type TYPE tadir-object, diff --git a/src/zabapgit_git.prog.abap b/src/zabapgit_git.prog.abap index fbff686d3..1ad56841b 100644 --- a/src/zabapgit_git.prog.abap +++ b/src/zabapgit_git.prog.abap @@ -1176,12 +1176,18 @@ CLASS lcl_git_porcelain IMPLEMENTATION. ASSERT sy-subrc = 0. * new commit + ls_commit-committer = |{ is_comment-committer-name + } <{ is_comment-committer-email }> { lv_time }|. + IF is_comment-author-name IS NOT INITIAL. + ls_commit-author = |{ is_comment-author-name + } <{ is_comment-author-email }> { lv_time }|. + ELSE. + ls_commit-author = ls_commit-committer. + ENDIF. + ls_commit-tree = -sha1. ls_commit-parent = io_stage->get_branch_sha1( ). ls_commit-parent2 = io_stage->get_merge_source( ). - CONCATENATE is_comment-username space '<' is_comment-email '>' space lv_time - INTO ls_commit-author RESPECTING BLANKS. - ls_commit-committer = ls_commit-author. ls_commit-body = is_comment-comment. lv_commit = lcl_git_pack=>encode_commit( ls_commit ). diff --git a/src/zabapgit_html_action_utils.prog.abap b/src/zabapgit_html_action_utils.prog.abap index 8de0a7462..ccf844469 100644 --- a/src/zabapgit_html_action_utils.prog.abap +++ b/src/zabapgit_html_action_utils.prog.abap @@ -293,11 +293,12 @@ CLASS lcl_html_action_utils IMPLEMENTATION. lt_fields = cl_http_utility=>if_http_utility~string_to_fields( lv_string ). field_keys_to_upper( CHANGING ct_fields = lt_fields ). - get_field( EXPORTING name = 'REPO_KEY' it = lt_fields CHANGING cv = es_fields ). - get_field( EXPORTING name = 'USERNAME' it = lt_fields CHANGING cv = es_fields ). - get_field( EXPORTING name = 'EMAIL' it = lt_fields CHANGING cv = es_fields ). - get_field( EXPORTING name = 'COMMENT' it = lt_fields CHANGING cv = es_fields ). - get_field( EXPORTING name = 'BODY' it = lt_fields CHANGING cv = es_fields ). + get_field( EXPORTING name = 'COMMITTER_NAME' it = lt_fields CHANGING cv = es_fields ). + get_field( EXPORTING name = 'COMMITTER_EMAIL' it = lt_fields CHANGING cv = es_fields ). + get_field( EXPORTING name = 'AUTHOR_NAME' it = lt_fields CHANGING cv = es_fields ). + get_field( EXPORTING name = 'AUTHOR_EMAIL' it = lt_fields CHANGING cv = es_fields ). + get_field( EXPORTING name = 'COMMENT' it = lt_fields CHANGING cv = es_fields ). + get_field( EXPORTING name = 'BODY' it = lt_fields CHANGING cv = es_fields ). ASSIGN COMPONENT 'BODY' OF STRUCTURE es_fields TO . ASSERT IS ASSIGNED. diff --git a/src/zabapgit_http.prog.abap b/src/zabapgit_http.prog.abap index b8e12a738..9cfaba173 100644 --- a/src/zabapgit_http.prog.abap +++ b/src/zabapgit_http.prog.abap @@ -475,7 +475,7 @@ CLASS lcl_http IMPLEMENTATION. lo_digest TYPE REF TO lcl_http_digest. - lv_default_user = lcl_app=>user( )->get_repo_username( iv_url ). + lv_default_user = lcl_app=>user( )->get_repo_login( iv_url ). lv_user = lv_default_user. lcl_password_dialog=>popup( @@ -490,8 +490,8 @@ CLASS lcl_http IMPLEMENTATION. ENDIF. IF lv_user <> lv_default_user. - lcl_app=>user( )->set_repo_username( iv_url = iv_url - iv_username = lv_user ). + lcl_app=>user( )->set_repo_login( iv_url = iv_url + iv_login = lv_user ). ENDIF. " Offer two factor authentication if it is available and required diff --git a/src/zabapgit_page_commit.prog.abap b/src/zabapgit_page_commit.prog.abap index 2a752d362..76b10187d 100644 --- a/src/zabapgit_page_commit.prog.abap +++ b/src/zabapgit_page_commit.prog.abap @@ -35,7 +35,13 @@ CLASS lcl_gui_page_commit DEFINITION FINAL INHERITING FROM lcl_gui_page. RAISING lcx_exception, render_form RETURNING VALUE(ro_html) TYPE REF TO lcl_html - RAISING lcx_exception. + RAISING lcx_exception, + render_text_input + IMPORTING iv_name TYPE string + iv_label TYPE string + iv_value TYPE string OPTIONAL + iv_max_length TYPE string OPTIONAL + RETURNING VALUE(ro_html) TYPE REF TO lcl_html. ENDCLASS. @@ -60,6 +66,8 @@ CLASS lcl_gui_page_commit IMPLEMENTATION. lcl_html_action_utils=>parse_commit_request( EXPORTING it_postdata = it_postdata IMPORTING es_fields = ls_commit ). + ls_commit-repo_key = mo_repo->get_key( ). + lcl_services_git=>commit( is_commit = ls_commit io_repo = mo_repo io_stage = mo_stage ). @@ -124,6 +132,27 @@ CLASS lcl_gui_page_commit IMPLEMENTATION. ENDMETHOD. "render_stage + METHOD render_text_input. + + DATA lv_attrs TYPE string. + + CREATE OBJECT ro_html. + + IF iv_value IS NOT INITIAL. + lv_attrs = | value="{ iv_value }"|. + ENDIF. + + IF iv_max_length IS NOT INITIAL. + lv_attrs = | maxlength="{ iv_max_length }"|. + ENDIF. + + ro_html->add( '
' ). + ro_html->add( || ). + ro_html->add( || ). + ro_html->add( '
' ). + + ENDMETHOD. " render_text_input + METHOD render_form. DATA: lo_user TYPE REF TO lcl_persistence_user, @@ -138,58 +167,53 @@ CLASS lcl_gui_page_commit IMPLEMENTATION. lo_user = lcl_app=>user( ). lv_key = mo_repo->get_key( ). - lv_user = lo_user->get_repo_username( mo_repo->get_url( ) ). + lv_user = lo_user->get_repo_git_user_name( mo_repo->get_url( ) ). IF lv_user IS INITIAL. - lv_user = lo_user->get_username( ). + lv_user = lo_user->get_default_git_user_name( ). ENDIF. - lv_email = lo_user->get_repo_email( mo_repo->get_url( ) ). + lv_email = lo_user->get_repo_git_user_email( mo_repo->get_url( ) ). IF lv_email IS INITIAL. - lv_email = lo_user->get_email( ). + lv_email = lo_user->get_default_git_user_email( ). ENDIF. CREATE OBJECT ro_html. - ro_html->add( '
' ). - ro_html->add( '
' ). - ro_html->add( || ). - ro_html->add( '' ). + ro_html->add( '
' ). + ro_html->add( '' ). - ro_html->add( '
' ). - ro_html->add( '' ). - ro_html->add( '' ). - ro_html->add( '' ). + ro_html->add( render_text_input( iv_name = 'committer_name' + iv_label = 'committer name' + iv_value = lv_user ) ). - ro_html->add( '' ). - ro_html->add( '' ). - ro_html->add( '' ). - ro_html->add( '' ). + ro_html->add( render_text_input( iv_name = 'committer_email' + iv_label = 'committer e-mail' + iv_value = lv_email ) ). - ro_html->add( '' ). - ro_html->add( '' ). - ro_html->add( '' ). - ro_html->add( '' ). + ro_html->add( render_text_input( iv_name = 'comment' + iv_label = 'comment' + iv_max_length = '50' ) ). - ro_html->add( '' ). - ro_html->add( '' ). - ro_html->add( '' ). - ro_html->add( '' ). + ro_html->add( render_text_input( iv_name = 'author_name' + iv_label = 'author name' ) ). + + ro_html->add( render_text_input( iv_name = 'author_email' + iv_label = 'author e-mail' ) ). - ro_html->add( '
username' ). - ro_html->add( || ). - ro_html->add( '
email' ). - ro_html->add( || ). - ro_html->add( '
comment' ). - ro_html->add( - '' ). - ro_html->add( '
body' ). - ro_html->add( '' ). + ro_html->add( '
' ). + ro_html->add( '' ). + ro_html->add( '' ). + ro_html->add( '' ). + ro_html->add( '
' ). - ro_html->add( '' ). "Hmmm ... reconsider + ro_html->add( '
' ). + ro_html->add( '' ). + ro_html->add( 'Optionally,' + && ' specify author (same as committer by default)' ). + ro_html->add( '
' ). - ro_html->add( '
' ). ro_html->add( '
' ). - ro_html->add( '
' ). ENDMETHOD. "render_form @@ -206,7 +230,7 @@ CLASS lcl_gui_page_commit IMPLEMENTATION. iv_typ = gc_action_type-onclick iv_opt = gc_html_opt-strong ) ##NO_TEXT. - lo_toolbar->add( iv_act = 'commit_cancel' + lo_toolbar->add( iv_act = c_action-commit_cancel iv_txt = 'Cancel' iv_opt = gc_html_opt-cancel ) ##NO_TEXT. @@ -219,7 +243,7 @@ CLASS lcl_gui_page_commit IMPLEMENTATION. METHOD scripts. CREATE OBJECT ro_html. - _add 'setInitialFocus("commit_msg");'. + _add 'setInitialFocus("comment");'. ENDMETHOD. "scripts diff --git a/src/zabapgit_persistence.prog.abap b/src/zabapgit_persistence.prog.abap index 18e27bca7..1a55d7eb7 100644 --- a/src/zabapgit_persistence.prog.abap +++ b/src/zabapgit_persistence.prog.abap @@ -364,19 +364,19 @@ CLASS lcl_persistence_user DEFINITION FINAL CREATE PRIVATE FRIENDS lcl_app. TYPES: tt_favorites TYPE lcl_persistence_repo=>tt_repo_keys. - METHODS set_username + METHODS set_default_git_user_name IMPORTING iv_username TYPE string RAISING lcx_exception. - METHODS get_username + METHODS get_default_git_user_name RETURNING VALUE(rv_username) TYPE string RAISING lcx_exception. - METHODS set_email + METHODS set_default_git_user_email IMPORTING iv_email TYPE string RAISING lcx_exception. - METHODS get_email + METHODS get_default_git_user_email RETURNING VALUE(rv_email) TYPE string RAISING lcx_exception. @@ -388,22 +388,32 @@ CLASS lcl_persistence_user DEFINITION FINAL CREATE PRIVATE FRIENDS lcl_app. RETURNING VALUE(rv_key) TYPE lcl_persistence_repo=>ty_repo-key RAISING lcx_exception. - METHODS set_repo_username + METHODS set_repo_git_user_name IMPORTING iv_url TYPE lcl_persistence_repo=>ty_repo-url iv_username TYPE string RAISING lcx_exception. - METHODS get_repo_username + METHODS get_repo_git_user_name IMPORTING iv_url TYPE lcl_persistence_repo=>ty_repo-url RETURNING VALUE(rv_username) TYPE string RAISING lcx_exception. - METHODS set_repo_email + METHODS set_repo_login + IMPORTING iv_url TYPE lcl_persistence_repo=>ty_repo-url + iv_login TYPE string + RAISING lcx_exception. + + METHODS get_repo_login + IMPORTING iv_url TYPE lcl_persistence_repo=>ty_repo-url + RETURNING VALUE(rv_login) TYPE string + RAISING lcx_exception. + + METHODS set_repo_git_user_email IMPORTING iv_url TYPE lcl_persistence_repo=>ty_repo-url iv_email TYPE string RAISING lcx_exception. - METHODS get_repo_email + METHODS get_repo_git_user_email IMPORTING iv_url TYPE lcl_persistence_repo=>ty_repo-url RETURNING VALUE(rv_email) TYPE string RAISING lcx_exception. @@ -450,23 +460,25 @@ CLASS lcl_persistence_user DEFINITION FINAL CREATE PRIVATE FRIENDS lcl_app. DATA: mv_user TYPE xubname. - TYPES: BEGIN OF ty_repo_config, - url TYPE lcl_persistence_repo=>ty_repo-url, - username TYPE string, - email TYPE string, - END OF ty_repo_config. + TYPES: + BEGIN OF ty_repo_config, + url TYPE lcl_persistence_repo=>ty_repo-url, + login TYPE string, + git_user TYPE ty_git_user, + END OF ty_repo_config. + TYPES: ty_repo_config_tt TYPE STANDARD TABLE OF ty_repo_config WITH DEFAULT KEY. - TYPES: BEGIN OF ty_user, - username TYPE string, - email TYPE string, - repo_show TYPE lcl_persistence_repo=>ty_repo-key, - repo_config TYPE ty_repo_config_tt, - hide_files TYPE abap_bool, - changes_only TYPE abap_bool, - diff_unified TYPE abap_bool, - favorites TYPE tt_favorites, - END OF ty_user. + TYPES: + BEGIN OF ty_user, + default_git_user TYPE ty_git_user, + repo_show TYPE lcl_persistence_repo=>ty_repo-key, + repo_config TYPE ty_repo_config_tt, + hide_files TYPE abap_bool, + changes_only TYPE abap_bool, + diff_unified TYPE abap_bool, + favorites TYPE tt_favorites, + END OF ty_user. METHODS constructor IMPORTING iv_user TYPE xubname DEFAULT sy-uname. @@ -576,39 +588,39 @@ CLASS lcl_persistence_user IMPLEMENTATION. ENDMETHOD. - METHOD set_username. + METHOD set_default_git_user_name. DATA: ls_user TYPE ty_user. ls_user = read( ). - ls_user-username = iv_username. + ls_user-default_git_user-name = iv_username. update( ls_user ). ENDMETHOD. - METHOD get_username. + METHOD get_default_git_user_name. - rv_username = read( )-username. + rv_username = read( )-default_git_user-name. ENDMETHOD. - METHOD set_email. + METHOD set_default_git_user_email. DATA: ls_user TYPE ty_user. ls_user = read( ). - ls_user-email = iv_email. + ls_user-default_git_user-email = iv_email. update( ls_user ). ENDMETHOD. - METHOD get_email. + METHOD get_default_git_user_email. - rv_email = read( )-email. + rv_email = read( )-default_git_user-email. ENDMETHOD. @@ -641,35 +653,51 @@ CLASS lcl_persistence_user IMPLEMENTATION. ENDMETHOD. "update_repo_config - METHOD set_repo_username. + METHOD set_repo_git_user_name. DATA: ls_repo_config TYPE ty_repo_config. - ls_repo_config = read_repo_config( iv_url ). - ls_repo_config-username = iv_username. + ls_repo_config = read_repo_config( iv_url ). + ls_repo_config-git_user-name = iv_username. update_repo_config( iv_url = iv_url is_repo_config = ls_repo_config ). ENDMETHOD. "set_repo_username - METHOD get_repo_username. + METHOD get_repo_git_user_name. - rv_username = read_repo_config( iv_url )-username. + rv_username = read_repo_config( iv_url )-git_user-name. ENDMETHOD. "get_repo_username - METHOD set_repo_email. + METHOD set_repo_login. DATA: ls_repo_config TYPE ty_repo_config. ls_repo_config = read_repo_config( iv_url ). - ls_repo_config-email = iv_email. + ls_repo_config-login = iv_login. + update_repo_config( iv_url = iv_url is_repo_config = ls_repo_config ). + + ENDMETHOD. "set_repo_login + + METHOD get_repo_login. + + rv_login = read_repo_config( iv_url )-login. + + ENDMETHOD. "get_repo_login + + METHOD set_repo_git_user_email. + + DATA: ls_repo_config TYPE ty_repo_config. + + ls_repo_config = read_repo_config( iv_url ). + ls_repo_config-git_user-email = iv_email. update_repo_config( iv_url = iv_url is_repo_config = ls_repo_config ). ENDMETHOD. "set_repo_email - METHOD get_repo_email. + METHOD get_repo_git_user_email. - rv_email = read_repo_config( iv_url )-email. + rv_email = read_repo_config( iv_url )-git_user-email. ENDMETHOD. "get_repo_email @@ -1238,8 +1266,8 @@ CLASS lcl_persistence_migrate IMPLEMENTATION. lt_users = lcl_user=>list( ). LOOP AT lt_users ASSIGNING . lo_user = lcl_app=>user( -user ). - lo_user->set_username( -username ). - lo_user->set_email( -email ). + lo_user->set_default_git_user_name( -username ). + lo_user->set_default_git_user_email( -email ). ENDLOOP. ENDMETHOD. diff --git a/src/zabapgit_services_git.prog.abap b/src/zabapgit_services_git.prog.abap index f64216d36..fcc5041b7 100644 --- a/src/zabapgit_services_git.prog.abap +++ b/src/zabapgit_services_git.prog.abap @@ -6,11 +6,13 @@ CLASS lcl_services_git DEFINITION FINAL. PUBLIC SECTION. TYPES: BEGIN OF ty_commit_fields, - repo_key TYPE lcl_persistence_repo=>ty_repo-key, - username TYPE string, - email TYPE string, - comment TYPE string, - body TYPE string, + repo_key TYPE lcl_persistence_repo=>ty_repo-key, + committer_name TYPE string, + committer_email TYPE string, + author_name TYPE string, + author_email TYPE string, + comment TYPE string, + body TYPE string, END OF ty_commit_fields. CLASS-METHODS pull @@ -183,22 +185,26 @@ CLASS lcl_services_git IMPLEMENTATION. lo_user TYPE REF TO lcl_persistence_user. lo_user = lcl_app=>user( ). - lo_user->set_repo_username( iv_url = io_repo->get_url( ) - iv_username = is_commit-username ). - lo_user->set_repo_email( iv_url = io_repo->get_url( ) - iv_email = is_commit-email ). + lo_user->set_repo_git_user_name( iv_url = io_repo->get_url( ) + iv_username = is_commit-committer_name ). + lo_user->set_repo_git_user_email( iv_url = io_repo->get_url( ) + iv_email = is_commit-committer_email ). - IF is_commit-username IS INITIAL. - lcx_exception=>raise( 'Commit: empty username' ). - ELSEIF is_commit-email IS INITIAL. - lcx_exception=>raise( 'Commit: empty email' ). + IF is_commit-committer_name IS INITIAL. + lcx_exception=>raise( 'Commit: Committer name empty' ). + ELSEIF is_commit-committer_email IS INITIAL. + lcx_exception=>raise( 'Commit: Committer email empty' ). + ELSEIF is_commit-author_email IS NOT INITIAL AND is_commit-author_name IS INITIAL. + lcx_exception=>raise( 'Commit: Author email empty' ). " Opposite should be OK ? ELSEIF is_commit-comment IS INITIAL. lcx_exception=>raise( 'Commit: empty comment' ). ENDIF. - ls_comment-username = is_commit-username. - ls_comment-email = is_commit-email. - ls_comment-comment = is_commit-comment. + ls_comment-committer-name = is_commit-committer_name. + ls_comment-committer-email = is_commit-committer_email. + ls_comment-author-name = is_commit-author_name. + ls_comment-author-email = is_commit-author_email. + ls_comment-comment = is_commit-comment. IF NOT is_commit-body IS INITIAL. CONCATENATE ls_comment-comment '' is_commit-body From 545bd5dea7de00a476e13b95872b477fb1ebdaca Mon Sep 17 00:00:00 2001 From: larshp Date: Thu, 23 Feb 2017 15:57:52 +0000 Subject: [PATCH 08/28] SFPF support #98 --- src/zabapgit_object_serializing.prog.abap | 1 + src/zabapgit_object_sfpf.prog.abap | 225 ++++++++++++++++++++++ src/zabapgit_object_sfpf.prog.xml | 22 +++ src/zabapgit_object_sfpi.prog.abap | 56 +----- 4 files changed, 249 insertions(+), 55 deletions(-) create mode 100644 src/zabapgit_object_sfpf.prog.abap create mode 100644 src/zabapgit_object_sfpf.prog.xml diff --git a/src/zabapgit_object_serializing.prog.abap b/src/zabapgit_object_serializing.prog.abap index 33ad3c7e9..f8153fd7d 100644 --- a/src/zabapgit_object_serializing.prog.abap +++ b/src/zabapgit_object_serializing.prog.abap @@ -29,6 +29,7 @@ INCLUDE zabapgit_object_pinf. INCLUDE zabapgit_object_prog. INCLUDE zabapgit_object_sfbf. INCLUDE zabapgit_object_sfbs. +INCLUDE zabapgit_object_sfpf. INCLUDE zabapgit_object_sfpi. INCLUDE zabapgit_object_sfsw. INCLUDE zabapgit_object_shi3. diff --git a/src/zabapgit_object_sfpf.prog.abap b/src/zabapgit_object_sfpf.prog.abap new file mode 100644 index 000000000..ce515d552 --- /dev/null +++ b/src/zabapgit_object_sfpf.prog.abap @@ -0,0 +1,225 @@ +*&---------------------------------------------------------------------* +*& Include ZABAPGIT_OBJECT_DOMA +*&---------------------------------------------------------------------* + +*----------------------------------------------------------------------* +* CLASS lcl_object_doma DEFINITION +*----------------------------------------------------------------------* +* +*----------------------------------------------------------------------* +CLASS lcl_object_sfpf DEFINITION INHERITING FROM lcl_objects_super FINAL. + + PUBLIC SECTION. + INTERFACES lif_object. + ALIASES mo_files FOR lif_object~mo_files. + + CLASS-METHODS: + fix_oref + IMPORTING ii_document TYPE REF TO if_ixml_document. + + PRIVATE SECTION. + METHODS: + load + RETURNING VALUE(ri_wb_form) TYPE REF TO if_fp_wb_form + RAISING lcx_exception, + form_to_xstring + RETURNING VALUE(rv_xstr) TYPE xstring + RAISING lcx_exception. + +ENDCLASS. "lcl_object_doma DEFINITION + +*----------------------------------------------------------------------* +* CLASS lcl_object_doma IMPLEMENTATION +*----------------------------------------------------------------------* +* +*----------------------------------------------------------------------* +CLASS lcl_object_sfpf IMPLEMENTATION. + + METHOD lif_object~has_changed_since. + rv_changed = abap_true. + ENDMETHOD. "lif_object~has_changed_since + + METHOD lif_object~changed_by. + + SELECT SINGLE lastuser FROM fplayout + INTO rv_user + WHERE name = ms_item-obj_name + AND state = 'A'. + IF rv_user IS INITIAL. + SELECT SINGLE firstuser FROM fplayout + INTO rv_user + WHERE name = ms_item-obj_name + AND state = 'A'. + ENDIF. + IF rv_user IS INITIAL. + rv_user = c_user_unknown. + ENDIF. + + ENDMETHOD. + + METHOD lif_object~get_metadata. + rs_metadata = get_metadata( ). + ENDMETHOD. "lif_object~get_metadata + + METHOD lif_object~exists. + + DATA: lv_name TYPE fpname. + + SELECT SINGLE name FROM fplayout + INTO lv_name + WHERE name = ms_item-obj_name + AND state = 'A'. + rv_bool = boolc( sy-subrc = 0 ). + + ENDMETHOD. "lif_object~exists + + METHOD lif_object~jump. + lcx_exception=>raise( 'todo, SFPF jump' ). + ENDMETHOD. "jump + + METHOD lif_object~delete. + + DATA: lv_name TYPE fpname, + lo_wb_form TYPE REF TO cl_fp_wb_form. + + + lo_wb_form ?= load( ). + + lv_name = ms_item-obj_name. + + TRY. + lo_wb_form->delete( lv_name ). + CATCH cx_fp_api. + lcx_exception=>raise( 'SFPI error, delete' ). + ENDTRY. + + ENDMETHOD. "delete + + METHOD load. + + DATA: lv_name TYPE fpname. + + + lv_name = ms_item-obj_name. + + TRY. + ri_wb_form = cl_fp_wb_form=>load( lv_name ). + CATCH cx_fp_api. + lcx_exception=>raise( 'SFPF error, load' ). + ENDTRY. + + ENDMETHOD. + + METHOD form_to_xstring. + + DATA: lv_xstr TYPE xstring, + li_fp_form TYPE REF TO if_fp_form, + li_wb_form TYPE REF TO if_fp_wb_form. + + + TRY. + li_wb_form = load( ). + li_fp_form ?= li_wb_form->get_object( ). + rv_xstr = cl_fp_helper=>convert_form_to_xstring( li_fp_form ). + CATCH cx_fp_api. + lcx_exception=>raise( 'SFPF error, form_to_xstring' ). + ENDTRY. + + ENDMETHOD. + + METHOD fix_oref. + + DATA: li_iterator TYPE REF TO if_ixml_node_iterator, + lv_name TYPE string, + lv_value TYPE string, + lv_new TYPE n LENGTH 3, + lv_old TYPE string, + lt_map TYPE STANDARD TABLE OF string WITH DEFAULT KEY, + li_attr_map TYPE REF TO if_ixml_named_node_map, + li_attr TYPE REF TO if_ixml_node, + li_node TYPE REF TO if_ixml_node. + + DEFINE _lookup. + read table lt_map from &1 transporting no fields. + if sy-subrc <> 0. + append &1 to lt_map. + read table lt_map from &1 transporting no fields. + endif. + lv_new = sy-tabix + 100. + END-OF-DEFINITION. + + + li_iterator = ii_document->create_iterator( ). + li_node = li_iterator->get_next( ). + WHILE NOT li_node IS INITIAL. + li_attr_map = li_node->get_attributes( ). + + IF li_attr_map IS BOUND. + li_attr = li_attr_map->get_named_item_ns( 'href' ). + IF li_attr IS BOUND. + lv_old = li_attr->get_value( ). + IF lv_old(2) = '#o'. + _lookup lv_old+1. + li_attr->set_value( '#o' && lv_new ). + ENDIF. + ENDIF. + + li_attr = li_attr_map->get_named_item_ns( 'id' ). + IF li_attr IS BOUND. + lv_old = li_attr->get_value( ). + IF lv_old(1) = 'o'. + _lookup lv_old. + li_attr->set_value( 'o' && lv_new ). + ENDIF. + ENDIF. + ENDIF. + + li_node = li_iterator->get_next( ). + ENDWHILE. + + ENDMETHOD. + + METHOD lif_object~serialize. + + DATA: lv_xstr TYPE xstring, + li_document TYPE REF TO if_ixml_document. + + + lv_xstr = form_to_xstring( ). + li_document = cl_ixml_80_20=>parse_to_document( stream_xstring = lv_xstr ). + fix_oref( li_document ). + io_xml->set_raw( li_document->get_root_element( ) ). + + ENDMETHOD. "serialize + + METHOD lif_object~deserialize. + + DATA: lv_xstr TYPE xstring, + lv_name TYPE fpname, + li_wb_object TYPE REF TO if_fp_wb_form, + li_form TYPE REF TO if_fp_form. + + + lv_name = ms_item-obj_name. + lv_xstr = cl_ixml_80_20=>render_to_xstring( io_xml->get_raw( ) ). + + TRY. + li_form = cl_fp_helper=>convert_xstring_to_form( lv_xstr ). + tadir_insert( iv_package ). + li_wb_object = cl_fp_wb_form=>create( i_name = lv_name + i_form = li_form ). + li_wb_object->save( ). + li_wb_object->free( ). + CATCH cx_fp_api. + lcx_exception=>raise( 'SFPF error, deserialize' ). + ENDTRY. + + lcl_objects_activation=>add_item( ms_item ). + + ENDMETHOD. "deserialize + + METHOD lif_object~compare_to_remote_version. + CREATE OBJECT ro_comparison_result TYPE lcl_null_comparison_result. + ENDMETHOD. + +ENDCLASS. "lcl_object_doma IMPLEMENTATION diff --git a/src/zabapgit_object_sfpf.prog.xml b/src/zabapgit_object_sfpf.prog.xml new file mode 100644 index 000000000..bfd12fb70 --- /dev/null +++ b/src/zabapgit_object_sfpf.prog.xml @@ -0,0 +1,22 @@ + + + + + + ZABAPGIT_OBJECT_SFPF + A + X + I + E + X + + + + R + Include ZABAPGIT_OBJECT_DOMA + 28 + + + + + diff --git a/src/zabapgit_object_sfpi.prog.abap b/src/zabapgit_object_sfpi.prog.abap index 930151f6d..d058e0a32 100644 --- a/src/zabapgit_object_sfpi.prog.abap +++ b/src/zabapgit_object_sfpi.prog.abap @@ -18,8 +18,6 @@ CLASS lcl_object_sfpi DEFINITION INHERITING FROM lcl_objects_super FINAL. load RETURNING VALUE(ri_wb_interface) TYPE REF TO if_fp_wb_interface RAISING lcx_exception, - fix_oref - IMPORTING ii_document TYPE REF TO if_ixml_document, interface_to_xstring RETURNING VALUE(rv_xstr) TYPE xstring RAISING lcx_exception. @@ -125,58 +123,6 @@ CLASS lcl_object_sfpi IMPLEMENTATION. ENDMETHOD. - METHOD fix_oref. - - DATA: li_iterator TYPE REF TO if_ixml_node_iterator, - lv_name TYPE string, - lv_value TYPE string, - lv_new TYPE n LENGTH 3, - lv_old TYPE string, - lt_map TYPE STANDARD TABLE OF string WITH DEFAULT KEY, - li_attr_map TYPE REF TO if_ixml_named_node_map, - li_attr TYPE REF TO if_ixml_node, - li_node TYPE REF TO if_ixml_node. - - DEFINE _lookup. - read table lt_map from &1 transporting no fields. - if sy-subrc <> 0. - append &1 to lt_map. - read table lt_map from &1 transporting no fields. - endif. - lv_new = sy-tabix + 100. - END-OF-DEFINITION. - - - li_iterator = ii_document->create_iterator( ). - li_node = li_iterator->get_next( ). - WHILE NOT li_node IS INITIAL. - li_attr_map = li_node->get_attributes( ). - - IF li_attr_map IS BOUND. - li_attr = li_attr_map->get_named_item_ns( 'href' ). - IF li_attr IS BOUND. - lv_old = li_attr->get_value( ). - IF lv_old(2) = '#o'. - _lookup lv_old+1. - li_attr->set_value( '#o' && lv_new ). - ENDIF. - ENDIF. - - li_attr = li_attr_map->get_named_item_ns( 'id' ). - IF li_attr IS BOUND. - lv_old = li_attr->get_value( ). - IF lv_old(1) = 'o'. - _lookup lv_old. - li_attr->set_value( 'o' && lv_new ). - ENDIF. - ENDIF. - ENDIF. - - li_node = li_iterator->get_next( ). - ENDWHILE. - - ENDMETHOD. - METHOD lif_object~serialize. DATA: lv_xstr TYPE xstring, @@ -185,7 +131,7 @@ CLASS lcl_object_sfpi IMPLEMENTATION. lv_xstr = interface_to_xstring( ). li_document = cl_ixml_80_20=>parse_to_document( stream_xstring = lv_xstr ). - fix_oref( li_document ). + lcl_object_sfpf=>fix_oref( li_document ). io_xml->set_raw( li_document->get_root_element( ) ). ENDMETHOD. "serialize From dea480469d2a273d7bd7879ab673ed5d7c43d5dd Mon Sep 17 00:00:00 2001 From: larshp Date: Sat, 25 Feb 2017 10:00:14 +0000 Subject: [PATCH 09/28] v1.31.0 SFPF support Committer and author separated --- src/zabapgit.prog.abap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zabapgit.prog.abap b/src/zabapgit.prog.abap index 4d2441127..55725524a 100644 --- a/src/zabapgit.prog.abap +++ b/src/zabapgit.prog.abap @@ -3,7 +3,7 @@ REPORT zabapgit LINE-SIZE 100. * See http://www.abapgit.org CONSTANTS: gc_xml_version TYPE string VALUE 'v1.0.0', "#EC NOTEXT - gc_abap_version TYPE string VALUE 'v1.30.0'. "#EC NOTEXT + gc_abap_version TYPE string VALUE 'v1.31.0'. "#EC NOTEXT ******************************************************************************** * The MIT License (MIT) From 357690dfff5bff4525c82ebb45d16868f8fb7dec Mon Sep 17 00:00:00 2001 From: Lars Hvam Date: Sat, 25 Feb 2017 11:01:32 +0100 Subject: [PATCH 10/28] v1.31.0 --- changelog.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/changelog.txt b/changelog.txt index f778b4ec6..0a7ff6530 100644 --- a/changelog.txt +++ b/changelog.txt @@ -8,6 +8,11 @@ Legend + : added - : removed +2017-02-25 v1.31.0 +------------------ ++ SFPF support ++ Committer and author separated + 2017-02-22 v1.30.0 ------------------ + SFPI support From b58205b0cb23364930b210d7056ea8965677effd Mon Sep 17 00:00:00 2001 From: larshp Date: Sat, 4 Mar 2017 08:30:32 +0000 Subject: [PATCH 11/28] local dot abapgit state #630 --- src/zabapgit.prog.abap | 2 +- src/zabapgit_dot_abapgit.prog.abap | 33 ++++++----- src/zabapgit_folder_logic.prog.abap | 5 +- src/zabapgit_migrations.prog.abap | 47 +++++++++++++++- src/zabapgit_persistence.prog.abap | 41 +++++++++++--- src/zabapgit_repo.prog.abap | 13 +++-- src/zabapgit_repo_browser_util.prog.abap | 2 +- src/zabapgit_repo_impl.prog.abap | 71 +++++++++++++++--------- src/zabapgit_stage.prog.abap | 34 ++++++------ src/zabapgit_transport.prog.abap | 21 +++---- src/zabapgit_unit_test.prog.abap | 14 ++--- src/zabapgit_zip.prog.abap | 5 +- 12 files changed, 193 insertions(+), 95 deletions(-) diff --git a/src/zabapgit.prog.abap b/src/zabapgit.prog.abap index 55725524a..26be26008 100644 --- a/src/zabapgit.prog.abap +++ b/src/zabapgit.prog.abap @@ -45,8 +45,8 @@ INCLUDE zabapgit_xml. INCLUDE zabapgit_app. " Some deferred definitions here INCLUDE zabapgit_persistence_old. -INCLUDE zabapgit_persistence. INCLUDE zabapgit_dot_abapgit. +INCLUDE zabapgit_persistence. INCLUDE zabapgit_sap_package. INCLUDE zabapgit_folder_logic. diff --git a/src/zabapgit_dot_abapgit.prog.abap b/src/zabapgit_dot_abapgit.prog.abap index 72147df9f..ee93e0270 100644 --- a/src/zabapgit_dot_abapgit.prog.abap +++ b/src/zabapgit_dot_abapgit.prog.abap @@ -4,7 +4,7 @@ CLASS ltcl_dot_abapgit DEFINITION DEFERRED. -CLASS lcl_dot_abapgit DEFINITION CREATE PRIVATE FINAL FRIENDS ltcl_dot_abapgit. +CLASS lcl_dot_abapgit DEFINITION FINAL FRIENDS ltcl_dot_abapgit. PUBLIC SECTION. CONSTANTS: BEGIN OF c_folder_logic, @@ -12,9 +12,15 @@ CLASS lcl_dot_abapgit DEFINITION CREATE PRIVATE FINAL FRIENDS ltcl_dot_abapgit. full TYPE string VALUE 'FULL', END OF c_folder_logic. + TYPES: BEGIN OF ty_dot_abapgit, + master_language TYPE spras, + starting_folder TYPE string, + folder_logic TYPE string, + ignore TYPE STANDARD TABLE OF string WITH DEFAULT KEY, + END OF ty_dot_abapgit. + CLASS-METHODS: build_default - IMPORTING iv_master_language TYPE spras RETURNING VALUE(ro_dot_abapgit) TYPE REF TO lcl_dot_abapgit, deserialize IMPORTING iv_xstr TYPE xstring @@ -22,9 +28,13 @@ CLASS lcl_dot_abapgit DEFINITION CREATE PRIVATE FINAL FRIENDS ltcl_dot_abapgit. RAISING lcx_exception. METHODS: + constructor + IMPORTING is_data TYPE ty_dot_abapgit, serialize RETURNING VALUE(rv_xstr) TYPE xstring RAISING lcx_exception, + get_data + RETURNING VALUE(rs_data) TYPE ty_dot_abapgit, add_ignore IMPORTING iv_path TYPE string iv_filename TYPE string, @@ -46,25 +56,14 @@ CLASS lcl_dot_abapgit DEFINITION CREATE PRIVATE FINAL FRIENDS ltcl_dot_abapgit. get_master_language RETURNING VALUE(rv_language) TYPE spras, * set_master_language -* IMPORTING iv_language TYPE spras. +* IMPORTING iv_language TYPE spras, get_signature RETURNING VALUE(rs_signature) TYPE ty_file_signature RAISING lcx_exception. PRIVATE SECTION. - TYPES: BEGIN OF ty_dot_abapgit, - master_language TYPE spras, - starting_folder TYPE string, - folder_logic TYPE string, - ignore TYPE STANDARD TABLE OF string WITH DEFAULT KEY, - END OF ty_dot_abapgit. - DATA: ms_data TYPE ty_dot_abapgit. - METHODS: - constructor - IMPORTING is_data TYPE ty_dot_abapgit. - CLASS-METHODS: to_xml IMPORTING is_data TYPE ty_dot_abapgit @@ -113,7 +112,7 @@ CLASS lcl_dot_abapgit IMPLEMENTATION. DATA: ls_data TYPE ty_dot_abapgit. - ls_data-master_language = iv_master_language. + ls_data-master_language = sy-langu. ls_data-starting_folder = '/'. ls_data-folder_logic = c_folder_logic-prefix. @@ -129,6 +128,10 @@ CLASS lcl_dot_abapgit IMPLEMENTATION. ENDMETHOD. + METHOD get_data. + rs_data = ms_data. + ENDMETHOD. + METHOD to_xml. CALL TRANSFORMATION id diff --git a/src/zabapgit_folder_logic.prog.abap b/src/zabapgit_folder_logic.prog.abap index 68141281d..4729eac93 100644 --- a/src/zabapgit_folder_logic.prog.abap +++ b/src/zabapgit_folder_logic.prog.abap @@ -37,6 +37,9 @@ CLASS lcl_folder_logic IMPLEMENTATION. lv_length = strlen( io_dot->get_starting_folder( ) ). + IF lv_length > strlen( lv_path ). + lcx_exception=>raise( 'unexpected folder structure' ). + ENDIF. lv_path = iv_path+lv_length. lv_parent = iv_top. rv_package = iv_top. @@ -153,7 +156,7 @@ CLASS ltcl_folder_logic_helper IMPLEMENTATION. lo_dot TYPE REF TO lcl_dot_abapgit. - lo_dot = lcl_dot_abapgit=>build_default( sy-langu ). + lo_dot = lcl_dot_abapgit=>build_default( ). lo_dot->set_starting_folder( iv_starting ). lo_dot->set_folder_logic( iv_logic ). diff --git a/src/zabapgit_migrations.prog.abap b/src/zabapgit_migrations.prog.abap index cf708f7d1..7c311bc7b 100644 --- a/src/zabapgit_migrations.prog.abap +++ b/src/zabapgit_migrations.prog.abap @@ -3,26 +3,69 @@ *&---------------------------------------------------------------------* CLASS lcl_migrations DEFINITION FINAL. - PUBLIC SECTION. + PUBLIC SECTION. CLASS-METHODS run RAISING lcx_exception. + + PRIVATE SECTION. CLASS-METHODS rebuild_local_checksums_161112 RAISING lcx_exception. + CLASS-METHODS local_dot_abapgit + RAISING lcx_exception. ENDCLASS. "lcl_migrations CLASS lcl_migrations IMPLEMENTATION. METHOD run. + " Migrate STDTEXT to TABLE lcl_persistence_migrate=>run( ). " Rebuild local file checksums rebuild_local_checksums_161112( ). + " local .abapgit.xml state, issue #630 + local_dot_abapgit( ). + ENDMETHOD. " run. + METHOD local_dot_abapgit. + + DATA: lt_repos TYPE lcl_repo_srv=>ty_repo_tt, + lv_shown TYPE abap_bool, + lo_dot_abapgit TYPE REF TO lcl_dot_abapgit. + + FIELD-SYMBOLS: LIKE LINE OF lt_repos. + + + lt_repos = lcl_app=>repo_srv( )->list( ). + + LOOP AT lt_repos ASSIGNING . + lo_dot_abapgit = ->get_dot_abapgit( ). + IF lo_dot_abapgit->get_data( ) IS INITIAL. + IF ->is_offline( ) = abap_true. + lo_dot_abapgit = lcl_dot_abapgit=>build_default( ). + ELSE. + IF lv_shown = abap_false. + CALL FUNCTION 'POPUP_TO_INFORM' + EXPORTING + titel = 'Migration' + txt1 = '.abapgit.xml is migrated to local state' + txt2 = 'Login to remote repositories if needed'. + lv_shown = abap_true. + ENDIF. + ->refresh( ). + lo_dot_abapgit = ->find_remote_dot_abapgit( ). + ENDIF. + ->set_dot_abapgit( lo_dot_abapgit ). + ENDIF. + + ENDLOOP. + + ENDMETHOD. + METHOD rebuild_local_checksums_161112. DATA: lt_repos TYPE lcl_repo_srv=>ty_repo_tt, @@ -77,7 +120,7 @@ CLASS lcl_migrations IMPLEMENTATION. text_button_2 = 'Skip update' icon_button_2 = 'ICON_CANCEL' default_button = '2' - display_cancel_button = abap_false ). "#EC NOTEXT + display_cancel_button = abap_false ). "#EC NOTEXT IF lv_answer = '2'. RETURN. diff --git a/src/zabapgit_persistence.prog.abap b/src/zabapgit_persistence.prog.abap index 1a55d7eb7..2acae64cc 100644 --- a/src/zabapgit_persistence.prog.abap +++ b/src/zabapgit_persistence.prog.abap @@ -105,7 +105,7 @@ CLASS lcl_persistence_repo DEFINITION FINAL. package TYPE devclass, offline TYPE sap_bool, local_checksums TYPE ty_local_checksum_tt, - master_language TYPE spras, + dot_abapgit TYPE lcl_dot_abapgit=>ty_dot_abapgit, head_branch TYPE string, " HEAD symref of the repo, master branch write_protect TYPE sap_bool, " Deny destructive ops: pull, switch branch ... ignore_subpackages TYPE sap_bool, @@ -154,12 +154,18 @@ CLASS lcl_persistence_repo DEFINITION FINAL. iv_offline TYPE ty_repo_xml-offline RAISING lcx_exception. + METHODS update_dot_abapgit + IMPORTING iv_key TYPE ty_repo-key + is_dot_abapgit TYPE lcl_dot_abapgit=>ty_dot_abapgit + RAISING lcx_exception. + METHODS add IMPORTING iv_url TYPE string iv_branch_name TYPE string iv_branch TYPE ty_sha1 OPTIONAL iv_package TYPE devclass iv_offline TYPE sap_bool DEFAULT abap_false + is_dot_abapgit TYPE lcl_dot_abapgit=>ty_dot_abapgit RETURNING VALUE(rv_key) TYPE ty_repo-key RAISING lcx_exception. @@ -937,7 +943,7 @@ CLASS lcl_persistence_repo IMPLEMENTATION. ls_repo-sha1 = iv_branch. ls_repo-package = iv_package. ls_repo-offline = iv_offline. - ls_repo-master_language = sy-langu. + ls_repo-dot_abapgit = is_dot_abapgit. lv_repo_as_xml = to_xml( ls_repo ). @@ -949,6 +955,30 @@ CLASS lcl_persistence_repo IMPLEMENTATION. ENDMETHOD. + METHOD update_dot_abapgit. + + DATA: lt_content TYPE lcl_persistence_db=>tt_content, + ls_content LIKE LINE OF lt_content, + ls_repo TYPE ty_repo. + + + ASSERT NOT iv_key IS INITIAL. + + TRY. + ls_repo = read( iv_key ). + CATCH lcx_not_found. + lcx_exception=>raise( 'key not found' ). + ENDTRY. + + ls_repo-dot_abapgit = is_dot_abapgit. + ls_content-data_str = to_xml( ls_repo ). + + mo_db->update( iv_type = c_type_repo + iv_value = iv_key + iv_data = ls_content-data_str ). + + ENDMETHOD. + METHOD delete. DATA: lo_background TYPE REF TO lcl_persistence_background. @@ -1184,10 +1214,6 @@ CLASS lcl_persistence_repo IMPLEMENTATION. lcx_exception=>raise( 'Inconsistent repo metadata' ). ENDIF. -* field master_language is new, so default it for old repositories - IF rs_repo-master_language IS INITIAL. - rs_repo-master_language = sy-langu. - ENDIF. ENDMETHOD. METHOD to_xml. @@ -1251,7 +1277,8 @@ CLASS lcl_persistence_migrate IMPLEMENTATION. iv_branch_name = ls_repo-branch_name iv_branch = ls_repo-sha1 iv_package = ls_repo-package - iv_offline = ls_repo-offline ). + iv_offline = ls_repo-offline + is_dot_abapgit = lcl_dot_abapgit=>build_default( )->get_data( ) ). ENDLOOP. ENDMETHOD. diff --git a/src/zabapgit_repo.prog.abap b/src/zabapgit_repo.prog.abap index a64183b00..b6590bb16 100644 --- a/src/zabapgit_repo.prog.abap +++ b/src/zabapgit_repo.prog.abap @@ -40,6 +40,9 @@ CLASS lcl_repo DEFINITION ABSTRACT FRIENDS lcl_repo_srv. RAISING lcx_exception, get_dot_abapgit RETURNING VALUE(ro_dot_abapgit) TYPE REF TO lcl_dot_abapgit, + set_dot_abapgit + IMPORTING io_dot_abapgit TYPE REF TO lcl_dot_abapgit + RAISING lcx_exception, deserialize RAISING lcx_exception, refresh @@ -47,26 +50,25 @@ CLASS lcl_repo DEFINITION ABSTRACT FRIENDS lcl_repo_srv. RAISING lcx_exception, refresh_local, " For testing purposes, maybe removed later update_local_checksums - IMPORTING it_files TYPE ty_file_signatures_tt + IMPORTING it_files TYPE ty_file_signatures_tt RAISING lcx_exception, rebuild_local_checksums RAISING lcx_exception, + find_remote_dot_abapgit + RETURNING VALUE(ro_dot) TYPE REF TO lcl_dot_abapgit + RAISING lcx_exception, is_offline RETURNING VALUE(rv_offline) TYPE abap_bool RAISING lcx_exception. PROTECTED SECTION. - DATA: mt_local TYPE ty_files_item_tt, mt_remote TYPE ty_files_tt, - mo_dot_abapgit TYPE REF TO lcl_dot_abapgit, mv_do_local_refresh TYPE abap_bool, mv_last_serialization TYPE timestamp, ms_data TYPE lcl_persistence_repo=>ty_repo. METHODS: - find_dot_abapgit - RAISING lcx_exception, set IMPORTING iv_sha1 TYPE ty_sha1 OPTIONAL it_checksums TYPE lcl_persistence_repo=>ty_local_checksum_tt OPTIONAL @@ -74,6 +76,7 @@ CLASS lcl_repo DEFINITION ABSTRACT FRIENDS lcl_repo_srv. iv_branch_name TYPE lcl_persistence_repo=>ty_repo-branch_name OPTIONAL iv_head_branch TYPE lcl_persistence_repo=>ty_repo-head_branch OPTIONAL iv_offline TYPE lcl_persistence_repo=>ty_repo-offline OPTIONAL + is_dot_abapgit TYPE lcl_persistence_repo=>ty_repo-dot_abapgit OPTIONAL RAISING lcx_exception. ENDCLASS. "lcl_repo DEFINITION diff --git a/src/zabapgit_repo_browser_util.prog.abap b/src/zabapgit_repo_browser_util.prog.abap index 1be3130f0..cfbe126a2 100644 --- a/src/zabapgit_repo_browser_util.prog.abap +++ b/src/zabapgit_repo_browser_util.prog.abap @@ -184,7 +184,7 @@ CLASS lcl_repo_content_browser IMPLEMENTATION. * todo, offline projects should have an dot abapgit too lt_tadir = lcl_tadir=>read( iv_package = mo_repo->get_package( ) - io_dot = lcl_dot_abapgit=>build_default( sy-langu ) ). + io_dot = lcl_dot_abapgit=>build_default( ) ). LOOP AT lt_tadir ASSIGNING . APPEND INITIAL LINE TO rt_repo_items ASSIGNING . diff --git a/src/zabapgit_repo_impl.prog.abap b/src/zabapgit_repo_impl.prog.abap index 8b0421318..9bfbe772a 100644 --- a/src/zabapgit_repo_impl.prog.abap +++ b/src/zabapgit_repo_impl.prog.abap @@ -11,8 +11,6 @@ CLASS lcl_repo_offline IMPLEMENTATION. mt_remote = it_files. - find_dot_abapgit( ). - ENDMETHOD. ENDCLASS. "lcl_repo_offline IMPLEMENTATION @@ -90,8 +88,6 @@ CLASS lcl_repo_online IMPLEMENTATION. mo_branches = lcl_git_transport=>branches( get_url( ) ). actualize_head_branch( ). - find_dot_abapgit( ). - mv_initialized = abap_true. ENDMETHOD. "refresh @@ -213,16 +209,18 @@ CLASS lcl_repo_online IMPLEMENTATION. METHOD handle_stage_ignore. - DATA: lv_add TYPE abap_bool, - lt_stage TYPE lcl_stage=>ty_stage_tt. + DATA: lv_add TYPE abap_bool, + lo_dot_abapgit TYPE REF TO lcl_dot_abapgit, + lt_stage TYPE lcl_stage=>ty_stage_tt. FIELD-SYMBOLS: LIKE LINE OF lt_stage. + lo_dot_abapgit = get_dot_abapgit( ). lt_stage = io_stage->get_all( ). LOOP AT lt_stage ASSIGNING WHERE method = lcl_stage=>c_method-ignore. - mo_dot_abapgit->add_ignore( + lo_dot_abapgit->add_ignore( iv_path = -file-path iv_filename = -file-filename ). @@ -238,7 +236,9 @@ CLASS lcl_repo_online IMPLEMENTATION. io_stage->add( iv_path = gc_root_dir iv_filename = gc_dot_abapgit - iv_data = mo_dot_abapgit->serialize( ) ). + iv_data = lo_dot_abapgit->serialize( ) ). + + set_dot_abapgit( lo_dot_abapgit ). ENDIF. ENDMETHOD. @@ -312,7 +312,7 @@ CLASS lcl_repo IMPLEMENTATION. ENDMETHOD. "constructor - METHOD find_dot_abapgit. + METHOD find_remote_dot_abapgit. FIELD-SYMBOLS: LIKE LINE OF mt_remote. @@ -321,7 +321,7 @@ CLASS lcl_repo IMPLEMENTATION. WITH KEY path = gc_root_dir filename = gc_dot_abapgit. IF sy-subrc = 0. - mo_dot_abapgit = lcl_dot_abapgit=>deserialize( -data ). + ro_dot = lcl_dot_abapgit=>deserialize( -data ). ENDIF. ENDMETHOD. @@ -340,7 +340,8 @@ CLASS lcl_repo IMPLEMENTATION. OR iv_url IS SUPPLIED OR iv_branch_name IS SUPPLIED OR iv_head_branch IS SUPPLIED - OR iv_offline IS SUPPLIED. + OR iv_offline IS SUPPLIED + OR is_dot_abapgit IS SUPPLIED. CREATE OBJECT lo_persistence. @@ -386,7 +387,14 @@ CLASS lcl_repo IMPLEMENTATION. ms_data-offline = iv_offline. ENDIF. - ENDMETHOD. "set_sha1 + IF is_dot_abapgit IS SUPPLIED. + lo_persistence->update_dot_abapgit( + iv_key = ms_data-key + is_dot_abapgit = is_dot_abapgit ). + ms_data-dot_abapgit = is_dot_abapgit. + ENDIF. + + ENDMETHOD. METHOD update_local_checksums. @@ -468,17 +476,22 @@ CLASS lcl_repo IMPLEMENTATION. METHOD deserialize. - DATA: lt_updated_files TYPE ty_file_signatures_tt. + DATA: lt_updated_files TYPE ty_file_signatures_tt, + lo_dot_abapgit TYPE REF TO lcl_dot_abapgit. - IF mo_dot_abapgit IS INITIAL. - mo_dot_abapgit = lcl_dot_abapgit=>build_default( ms_data-master_language ). - ENDIF. - IF mo_dot_abapgit->get_master_language( ) <> sy-langu. + + IF get_dot_abapgit( )->get_master_language( ) <> sy-langu. lcx_exception=>raise( 'Current login language does not match master language' ). ENDIF. + lo_dot_abapgit = find_remote_dot_abapgit( ). + IF lo_dot_abapgit IS BOUND. + set_dot_abapgit( lo_dot_abapgit ). + ENDIF. + lt_updated_files = lcl_objects=>deserialize( me ). - APPEND mo_dot_abapgit->get_signature( ) TO lt_updated_files. + + APPEND get_dot_abapgit( )->get_signature( ) TO lt_updated_files. CLEAR: mt_local, mv_last_serialization. @@ -524,13 +537,10 @@ CLASS lcl_repo IMPLEMENTATION. RETURN. ENDIF. - IF mo_dot_abapgit IS INITIAL. - mo_dot_abapgit = lcl_dot_abapgit=>build_default( ms_data-master_language ). - ENDIF. APPEND INITIAL LINE TO rt_files ASSIGNING . -file-path = gc_root_dir. -file-filename = gc_dot_abapgit. - -file-data = mo_dot_abapgit->serialize( ). + -file-data = get_dot_abapgit( )->serialize( ). -file-sha1 = lcl_hash=>sha1( iv_type = gc_type-blob iv_data = -file-data ). @@ -599,7 +609,13 @@ CLASS lcl_repo IMPLEMENTATION. ENDMETHOD. METHOD get_dot_abapgit. - ro_dot_abapgit = mo_dot_abapgit. + CREATE OBJECT ro_dot_abapgit + EXPORTING + is_data = ms_data-dot_abapgit. + ENDMETHOD. + + METHOD set_dot_abapgit. + set( is_dot_abapgit = io_dot_abapgit->get_data( ) ). ENDMETHOD. METHOD delete. @@ -636,7 +652,7 @@ CLASS lcl_repo IMPLEMENTATION. ENDMETHOD. "get_package METHOD get_master_language. - rv_language = ms_data-master_language. + rv_language = ms_data-dot_abapgit-master_language. ENDMETHOD. METHOD get_key. @@ -782,8 +798,8 @@ CLASS lcl_repo_srv IMPLEMENTATION. iv_url = iv_url iv_branch_name = iv_branch_name iv_package = iv_package - iv_offline = abap_false ). - + iv_offline = abap_false + is_dot_abapgit = lcl_dot_abapgit=>build_default( )->get_data( ) ). TRY. ls_repo = mo_persistence->read( lv_key ). CATCH lcx_not_found. @@ -810,7 +826,8 @@ CLASS lcl_repo_srv IMPLEMENTATION. iv_url = iv_url iv_branch_name = '' iv_package = iv_package - iv_offline = abap_true ). + iv_offline = abap_true + is_dot_abapgit = lcl_dot_abapgit=>build_default( )->get_data( ) ). TRY. ls_repo = mo_persistence->read( lv_key ). diff --git a/src/zabapgit_stage.prog.abap b/src/zabapgit_stage.prog.abap index 2567a3178..7b7f886bb 100644 --- a/src/zabapgit_stage.prog.abap +++ b/src/zabapgit_stage.prog.abap @@ -56,10 +56,10 @@ CLASS lcl_stage DEFINITION FINAL. IMPORTING iv_path TYPE ty_file-path iv_filename TYPE ty_file-filename RAISING lcx_exception, -* lookup -* IMPORTING iv_path TYPE ty_file-path -* iv_filename TYPE ty_file-filename -* RETURNING VALUE(rv_method) TYPE ty_method, + lookup + IMPORTING iv_path TYPE ty_file-path + iv_filename TYPE ty_file-filename + RETURNING VALUE(rv_method) TYPE ty_method, get_merge_source RETURNING VALUE(rv_source) TYPE ty_sha1, count @@ -103,19 +103,19 @@ CLASS lcl_stage IMPLEMENTATION. rv_branch = mv_branch_sha1. ENDMETHOD. -* METHOD lookup. -* -* DATA ls_stage LIKE LINE OF mt_stage. -* -* -* READ TABLE mt_stage INTO ls_stage -* WITH KEY file-path = iv_path -* file-filename = iv_filename. -* IF sy-subrc = 0. -* rv_method = ls_stage-method. -* ENDIF. -* -* ENDMETHOD. "lookup + METHOD lookup. + + DATA ls_stage LIKE LINE OF mt_stage. + + + READ TABLE mt_stage INTO ls_stage + WITH KEY file-path = iv_path + file-filename = iv_filename. + IF sy-subrc = 0. + rv_method = ls_stage-method. + ENDIF. + + ENDMETHOD. "lookup METHOD get_all. rt_stage = mt_stage. diff --git a/src/zabapgit_transport.prog.abap b/src/zabapgit_transport.prog.abap index 4d7bc6b6e..ba5c96d29 100644 --- a/src/zabapgit_transport.prog.abap +++ b/src/zabapgit_transport.prog.abap @@ -30,12 +30,13 @@ CLASS lcl_transport IMPLEMENTATION. METHOD zip. - DATA: lt_requests TYPE trwbo_requests, - lt_tadir TYPE scts_tadir, - lv_package TYPE devclass, - ls_data TYPE lcl_persistence_repo=>ty_repo, - lo_repo TYPE REF TO lcl_repo_offline, - lt_trkorr TYPE trwbo_request_headers. + DATA: lt_requests TYPE trwbo_requests, + lt_tadir TYPE scts_tadir, + lv_package TYPE devclass, + ls_data TYPE lcl_persistence_repo=>ty_repo, + lo_repo TYPE REF TO lcl_repo_offline, + lt_trkorr TYPE trwbo_request_headers. + lt_trkorr = popup( ). IF lines( lt_trkorr ) = 0. @@ -53,15 +54,15 @@ CLASS lcl_transport IMPLEMENTATION. lcx_exception=>raise( 'error finding super package' ). ENDIF. - ls_data-key = 'TZIP'. - ls_data-package = lv_package. - ls_data-master_language = sy-langu. + ls_data-key = 'TZIP'. + ls_data-package = lv_package. + ls_data-dot_abapgit = lcl_dot_abapgit=>build_default( )->get_data( ). CREATE OBJECT lo_repo EXPORTING is_data = ls_data. - lcl_zip=>export( io_repo = lo_repo + lcl_zip=>export( io_repo = lo_repo it_filter = lt_tadir ). ENDMETHOD. diff --git a/src/zabapgit_unit_test.prog.abap b/src/zabapgit_unit_test.prog.abap index 3c8ae49ae..2a0ab9b4d 100644 --- a/src/zabapgit_unit_test.prog.abap +++ b/src/zabapgit_unit_test.prog.abap @@ -397,7 +397,7 @@ CLASS ltcl_dot_abapgit IMPLEMENTATION. ls_after TYPE lcl_dot_abapgit=>ty_dot_abapgit. - lo_dot = lcl_dot_abapgit=>build_default( gc_english ). + lo_dot = lcl_dot_abapgit=>build_default( ). ls_before = lo_dot->ms_data. lo_dot = lcl_dot_abapgit=>deserialize( lo_dot->serialize( ) ). @@ -418,7 +418,7 @@ CLASS ltcl_dot_abapgit IMPLEMENTATION. lo_dot TYPE REF TO lcl_dot_abapgit. - lo_dot = lcl_dot_abapgit=>build_default( gc_english ). + lo_dot = lcl_dot_abapgit=>build_default( ). lv_ignored = lo_dot->is_ignored( iv_path = lc_path iv_filename = lc_filename ). cl_abap_unit_assert=>assert_equals( @@ -1986,7 +1986,7 @@ CLASS ltcl_file_status2 IMPLEMENTATION. lcl_file_status=>run_checks( io_log = lo_log it_results = lt_results - io_dot = lcl_dot_abapgit=>build_default( sy-langu ) + io_dot = lcl_dot_abapgit=>build_default( ) iv_top = '$Z$' ). assert_equals( act = lo_log->count( ) exp = 0 ). @@ -2004,7 +2004,7 @@ CLASS ltcl_file_status2 IMPLEMENTATION. lcl_file_status=>run_checks( io_log = lo_log it_results = lt_results - io_dot = lcl_dot_abapgit=>build_default( sy-langu ) + io_dot = lcl_dot_abapgit=>build_default( ) iv_top = '$Z$' ). " This one is not pure - incorrect path also triggers path vs package check @@ -2024,7 +2024,7 @@ CLASS ltcl_file_status2 IMPLEMENTATION. lcl_file_status=>run_checks( io_log = lo_log it_results = lt_results - io_dot = lcl_dot_abapgit=>build_default( sy-langu ) + io_dot = lcl_dot_abapgit=>build_default( ) iv_top = '$Z$' ). assert_equals( act = lo_log->count( ) exp = 1 ). @@ -2043,7 +2043,7 @@ CLASS ltcl_file_status2 IMPLEMENTATION. lcl_file_status=>run_checks( io_log = lo_log it_results = lt_results - io_dot = lcl_dot_abapgit=>build_default( sy-langu ) + io_dot = lcl_dot_abapgit=>build_default( ) iv_top = '$Z$' ). assert_equals( act = lo_log->count( ) exp = 1 ). @@ -2061,7 +2061,7 @@ CLASS ltcl_file_status2 IMPLEMENTATION. lcl_file_status=>run_checks( io_log = lo_log it_results = lt_results - io_dot = lcl_dot_abapgit=>build_default( sy-langu ) + io_dot = lcl_dot_abapgit=>build_default( ) iv_top = '$Z$' ). assert_equals( act = lo_log->count( ) diff --git a/src/zabapgit_zip.prog.abap b/src/zabapgit_zip.prog.abap index b27607ed9..f2618b319 100644 --- a/src/zabapgit_zip.prog.abap +++ b/src/zabapgit_zip.prog.abap @@ -432,13 +432,14 @@ CLASS lcl_zip IMPLEMENTATION. DATA: lo_repo TYPE REF TO lcl_repo_offline, ls_data TYPE lcl_persistence_repo=>ty_repo. + ls_data-package = lcl_popups=>popup_package_export( ). IF ls_data-package IS INITIAL. RAISE EXCEPTION TYPE lcx_cancel. ENDIF. - ls_data-key = 'DUMMY'. - ls_data-master_language = sy-langu. + ls_data-key = 'DUMMY'. + ls_data-dot_abapgit = lcl_dot_abapgit=>build_default( )->get_data( ). CREATE OBJECT lo_repo EXPORTING From 1cc5aa47cc48955470a477ce404b57f19d013f20 Mon Sep 17 00:00:00 2001 From: larshp Date: Sat, 4 Mar 2017 11:22:31 +0000 Subject: [PATCH 12/28] bugfix --- src/zabapgit_folder_logic.prog.abap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zabapgit_folder_logic.prog.abap b/src/zabapgit_folder_logic.prog.abap index 4729eac93..5303edf23 100644 --- a/src/zabapgit_folder_logic.prog.abap +++ b/src/zabapgit_folder_logic.prog.abap @@ -37,7 +37,7 @@ CLASS lcl_folder_logic IMPLEMENTATION. lv_length = strlen( io_dot->get_starting_folder( ) ). - IF lv_length > strlen( lv_path ). + IF lv_length > strlen( iv_path ). lcx_exception=>raise( 'unexpected folder structure' ). ENDIF. lv_path = iv_path+lv_length. From 3ad1662e0e7871fba59f06a86a0361793bf53b40 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sun, 5 Mar 2017 15:06:53 +0200 Subject: [PATCH 13/28] warnings diplayed in yellow #650 --- src/zabapgit_css_common.w3mi.data.css | 2 +- src/zabapgit_css_common.w3mi.xml | 2 +- src/zabapgit_file_status.prog.abap | 4 ++++ src/zabapgit_objects_impl.prog.abap | 1 + src/zabapgit_util.prog.abap | 24 ++++++++++++++++++++---- 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/zabapgit_css_common.w3mi.data.css b/src/zabapgit_css_common.w3mi.data.css index 31365ec0b..8bcfae494 100644 --- a/src/zabapgit_css_common.w3mi.data.css +++ b/src/zabapgit_css_common.w3mi.data.css @@ -38,7 +38,7 @@ input:focus, textarea:focus { .darkgrey { color: #808080 !important; } .attention { color: red !important; } .error { color: #d41919 !important; } -.warning { color: #e4ae0d !important; } +.warning { color: #efb301 !important; } .blue { color: #5e8dc9 !important; } .red { color: red !important; } diff --git a/src/zabapgit_css_common.w3mi.xml b/src/zabapgit_css_common.w3mi.xml index cbea95037..dbdbed67e 100644 --- a/src/zabapgit_css_common.w3mi.xml +++ b/src/zabapgit_css_common.w3mi.xml @@ -15,7 +15,7 @@ MI ZABAPGIT_CSS_COMMON filename - common.css + ~wwwtmp.css MI diff --git a/src/zabapgit_file_status.prog.abap b/src/zabapgit_file_status.prog.abap index ee105864a..f3109c138 100644 --- a/src/zabapgit_file_status.prog.abap +++ b/src/zabapgit_file_status.prog.abap @@ -103,6 +103,7 @@ CLASS lcl_file_status IMPLEMENTATION. iv_msgv2 = -obj_type iv_msgv3 = -obj_name iv_msgv4 = 'are not placed in the same folder' + iv_msgty = 'W' iv_rc = '1' ) ##no_text. ENDIF. ENDLOOP. @@ -117,6 +118,7 @@ CLASS lcl_file_status IMPLEMENTATION. io_log->add( iv_msgv1 = 'Package and path does not match for object,' iv_msgv2 = -obj_type iv_msgv3 = -obj_name + iv_msgty = 'W' iv_rc = '2' ) ##no_text. ENDIF. ENDLOOP. @@ -128,6 +130,7 @@ CLASS lcl_file_status IMPLEMENTATION. IF -filename IS NOT INITIAL AND -filename = ls_file-filename. io_log->add( iv_msgv1 = 'Multiple files with same filename,' iv_msgv2 = -filename + iv_msgty = 'W' iv_rc = '3' ) ##no_text. ENDIF. @@ -135,6 +138,7 @@ CLASS lcl_file_status IMPLEMENTATION. io_log->add( iv_msgv1 = 'Filename is empty for object' iv_msgv2 = -obj_type iv_msgv3 = -obj_name + iv_msgty = 'W' iv_rc = '4' ) ##no_text. ENDIF. diff --git a/src/zabapgit_objects_impl.prog.abap b/src/zabapgit_objects_impl.prog.abap index ced014a35..6510a1d3a 100644 --- a/src/zabapgit_objects_impl.prog.abap +++ b/src/zabapgit_objects_impl.prog.abap @@ -484,6 +484,7 @@ CLASS lcl_objects IMPLEMENTATION. io_log->add( iv_msgv1 = 'Object type ignored, not supported:' iv_msgv2 = is_item-obj_type iv_msgv3 = '-' + iv_msgty = 'E' iv_msgv4 = is_item-obj_name ) ##no_text. ENDIF. RETURN. diff --git a/src/zabapgit_util.prog.abap b/src/zabapgit_util.prog.abap index 87e8603a7..6e58940ed 100644 --- a/src/zabapgit_util.prog.abap +++ b/src/zabapgit_util.prog.abap @@ -1055,6 +1055,7 @@ CLASS lcl_log DEFINITION FINAL. iv_msgv2 TYPE csequence OPTIONAL iv_msgv3 TYPE csequence OPTIONAL iv_msgv4 TYPE csequence OPTIONAL + iv_msgty TYPE symsgty DEFAULT 'E' iv_rc TYPE balsort OPTIONAL, count RETURNING VALUE(rv_count) TYPE i, @@ -1075,7 +1076,9 @@ CLASS lcl_log IMPLEMENTATION. METHOD to_html. - DATA: lv_string TYPE string. + DATA: lv_class TYPE string, + lv_icon TYPE string, + lv_string TYPE string. FIELD-SYMBOLS: LIKE LINE OF mt_log. @@ -1086,10 +1089,23 @@ CLASS lcl_log IMPLEMENTATION. ENDIF. LOOP AT mt_log ASSIGNING . + CASE -msgty. + WHEN 'W'. + lv_icon = 'alert'. + lv_class = 'warning'. + WHEN 'E'. + lv_icon = 'flame'. + lv_class = 'error'. + WHEN OTHERS. " ??? unexpected + lv_icon = 'flame'. + lv_class = 'error'. + ENDCASE. + CONCATENATE -msgv1 -msgv2 -msgv3 -msgv4 INTO lv_string SEPARATED BY space. - ro_html->add( '' ). - ro_html->add_icon( iv_name = 'alert' iv_class = 'error' ). " warning CSS exists too + + ro_html->add( || ). + ro_html->add_icon( iv_name = lv_icon ). ro_html->add( lv_string ). ro_html->add( '' ). ENDLOOP. @@ -1101,7 +1117,7 @@ CLASS lcl_log IMPLEMENTATION. FIELD-SYMBOLS: LIKE LINE OF mt_log. APPEND INITIAL LINE TO mt_log ASSIGNING . - -msgty = 'W'. + -msgty = iv_msgty. " Error by default -msgid = '00'. -msgno = '001'. -msgv1 = iv_msgv1. From 6944b98208898dc07a4a25e96a30251471b7de2c Mon Sep 17 00:00:00 2001 From: larshp Date: Tue, 7 Mar 2017 09:03:08 +0000 Subject: [PATCH 14/28] fix typo --- src/zabapgit_objects.prog.abap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zabapgit_objects.prog.abap b/src/zabapgit_objects.prog.abap index f0f1a39f1..1243760bf 100644 --- a/src/zabapgit_objects.prog.abap +++ b/src/zabapgit_objects.prog.abap @@ -1111,7 +1111,7 @@ CLASS lcl_objects_program IMPLEMENTATION. * function module RPY_PROGRAM_INSERT cannot handle function group includes IF strlen( is_progdir-name ) > 30. - " special treatment for extenstions + " special treatment for extensions " if the program name exceeds 30 characters it is not a usual " ABAP program but might be some extension, which requires the internal " addition EXTENSION TYPE, see From 683362317d9b374c4478a2961dbd8472ec0a6799 Mon Sep 17 00:00:00 2001 From: Lars Hvam Date: Tue, 7 Mar 2017 18:58:07 +0100 Subject: [PATCH 15/28] v1.31.1 --- src/zabapgit.prog.abap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zabapgit.prog.abap b/src/zabapgit.prog.abap index 26be26008..3e1a01f7d 100644 --- a/src/zabapgit.prog.abap +++ b/src/zabapgit.prog.abap @@ -3,7 +3,7 @@ REPORT zabapgit LINE-SIZE 100. * See http://www.abapgit.org CONSTANTS: gc_xml_version TYPE string VALUE 'v1.0.0', "#EC NOTEXT - gc_abap_version TYPE string VALUE 'v1.31.0'. "#EC NOTEXT + gc_abap_version TYPE string VALUE 'v1.31.1'. "#EC NOTEXT ******************************************************************************** * The MIT License (MIT) From c85726ff073dfb0fc35b033497d2075ec70259b9 Mon Sep 17 00:00:00 2001 From: Lars Hvam Date: Tue, 7 Mar 2017 18:59:13 +0100 Subject: [PATCH 16/28] v1.31.1 --- changelog.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog.txt b/changelog.txt index 0a7ff6530..7829d44e5 100644 --- a/changelog.txt +++ b/changelog.txt @@ -8,6 +8,10 @@ Legend + : added - : removed +2017-03-07 v1.31.1 +------------------ +! local .abapgit.xml state, note migration is triggered automatically when executing abapGit + 2017-02-25 v1.31.0 ------------------ + SFPF support From fefce273e61272b2736ebe16883be5c09a81b683 Mon Sep 17 00:00:00 2001 From: larshp Date: Fri, 10 Mar 2017 14:30:43 +0000 Subject: [PATCH 17/28] refactor lcl_log->add --- src/zabapgit_file_status.prog.abap | 54 ++++++++++------------ src/zabapgit_objects_impl.prog.abap | 8 ++-- src/zabapgit_util.prog.abap | 72 ++++++++++++++++------------- 3 files changed, 67 insertions(+), 67 deletions(-) diff --git a/src/zabapgit_file_status.prog.abap b/src/zabapgit_file_status.prog.abap index f3109c138..032e16876 100644 --- a/src/zabapgit_file_status.prog.abap +++ b/src/zabapgit_file_status.prog.abap @@ -23,17 +23,17 @@ CLASS lcl_file_status DEFINITION FINAL CLASS-METHODS: calculate_status - IMPORTING iv_devclass TYPE devclass - it_local TYPE ty_files_item_tt - it_remote TYPE ty_files_tt - it_cur_state TYPE ty_file_signatures_tt - RETURNING VALUE(rt_results) TYPE ty_results_tt, + IMPORTING iv_devclass TYPE devclass + it_local TYPE ty_files_item_tt + it_remote TYPE ty_files_tt + it_cur_state TYPE ty_file_signatures_tt + RETURNING VALUE(rt_results) TYPE ty_results_tt, run_checks IMPORTING io_log TYPE REF TO lcl_log it_results TYPE ty_results_tt io_dot TYPE REF TO lcl_dot_abapgit iv_top TYPE devclass - RAISING lcx_exception, + RAISING lcx_exception, build_existing IMPORTING is_local TYPE ty_file_item is_remote TYPE ty_file @@ -49,9 +49,9 @@ CLASS lcl_file_status DEFINITION FINAL it_state TYPE ty_file_signatures_ts RETURNING VALUE(rs_result) TYPE ty_result, identify_object - IMPORTING iv_filename TYPE string - EXPORTING es_item TYPE ty_item - ev_is_xml TYPE abap_bool. + IMPORTING iv_filename TYPE string + EXPORTING es_item TYPE ty_item + ev_is_xml TYPE abap_bool. ENDCLASS. "lcl_file_status DEFINITION @@ -99,11 +99,9 @@ CLASS lcl_file_status IMPLEMENTATION. BINARY SEARCH. " Sorted above IF sy-subrc <> 0 OR -path <> -path. " All paths are same - io_log->add( iv_msgv1 = 'Files for object' - iv_msgv2 = -obj_type - iv_msgv3 = -obj_name - iv_msgv4 = 'are not placed in the same folder' - iv_msgty = 'W' + io_log->add( iv_msg = |Files for object { -obj_type }{ + -obj_name }are not placed in the same folder| + iv_type = 'W' iv_rc = '1' ) ##no_text. ENDIF. ENDLOOP. @@ -115,10 +113,9 @@ CLASS lcl_file_status IMPLEMENTATION. io_dot = io_dot iv_package = -package ). IF lv_path <> -path. - io_log->add( iv_msgv1 = 'Package and path does not match for object,' - iv_msgv2 = -obj_type - iv_msgv3 = -obj_name - iv_msgty = 'W' + io_log->add( iv_msg = |Package and path does not match for object, { + -obj_type } { -obj_name }| + iv_type = 'W' iv_rc = '2' ) ##no_text. ENDIF. ENDLOOP. @@ -128,18 +125,15 @@ CLASS lcl_file_status IMPLEMENTATION. LOOP AT lt_res_sort ASSIGNING . IF -filename IS NOT INITIAL AND -filename = ls_file-filename. - io_log->add( iv_msgv1 = 'Multiple files with same filename,' - iv_msgv2 = -filename - iv_msgty = 'W' - iv_rc = '3' ) ##no_text. + io_log->add( iv_msg = |Multiple files with same filename, { -filename }| + iv_type = 'W' + iv_rc = '3' ) ##no_text. ENDIF. IF -filename IS INITIAL. - io_log->add( iv_msgv1 = 'Filename is empty for object' - iv_msgv2 = -obj_type - iv_msgv3 = -obj_name - iv_msgty = 'W' - iv_rc = '4' ) ##no_text. + io_log->add( iv_msg = |Filename is empty for object { -obj_type } { -obj_name }| + iv_type = 'W' + iv_rc = '4' ) ##no_text. ENDIF. MOVE-CORRESPONDING TO ls_file. @@ -258,9 +252,9 @@ CLASS lcl_file_status IMPLEMENTATION. METHOD identify_object. - DATA: lv_name TYPE tadir-obj_name, - lv_type TYPE string, - lv_ext TYPE string. + DATA: lv_name TYPE tadir-obj_name, + lv_type TYPE string, + lv_ext TYPE string. " Guess object type and name SPLIT to_upper( iv_filename ) AT '.' INTO lv_name lv_type lv_ext. diff --git a/src/zabapgit_objects_impl.prog.abap b/src/zabapgit_objects_impl.prog.abap index 6510a1d3a..2e3ba26b3 100644 --- a/src/zabapgit_objects_impl.prog.abap +++ b/src/zabapgit_objects_impl.prog.abap @@ -481,11 +481,9 @@ CLASS lcl_objects IMPLEMENTATION. IF is_supported( is_item ) = abap_false. IF NOT io_log IS INITIAL. - io_log->add( iv_msgv1 = 'Object type ignored, not supported:' - iv_msgv2 = is_item-obj_type - iv_msgv3 = '-' - iv_msgty = 'E' - iv_msgv4 = is_item-obj_name ) ##no_text. + io_log->add( iv_msg = |Object type ignored, not supported: { is_item-obj_type + }-{ is_item-obj_name }| + iv_type = 'E' ). ENDIF. RETURN. ENDIF. diff --git a/src/zabapgit_util.prog.abap b/src/zabapgit_util.prog.abap index 6e58940ed..6f3b9a3e2 100644 --- a/src/zabapgit_util.prog.abap +++ b/src/zabapgit_util.prog.abap @@ -444,7 +444,7 @@ CLASS lcl_path IMPLEMENTATION. lv_index TYPE i, lt_split TYPE TABLE OF string. -" filename | c:\filename | /dir/filename | \\server\filename + " filename | c:\filename | /dir/filename | \\server\filename IF iv_path CA '/'. lv_split = '/'. ELSE. @@ -1051,12 +1051,9 @@ CLASS lcl_log DEFINITION FINAL. METHODS: add IMPORTING - iv_msgv1 TYPE csequence - iv_msgv2 TYPE csequence OPTIONAL - iv_msgv3 TYPE csequence OPTIONAL - iv_msgv4 TYPE csequence OPTIONAL - iv_msgty TYPE symsgty DEFAULT 'E' - iv_rc TYPE balsort OPTIONAL, + iv_msg TYPE csequence + iv_type TYPE symsgty DEFAULT 'E' + iv_rc TYPE balsort OPTIONAL, count RETURNING VALUE(rv_count) TYPE i, to_html @@ -1068,7 +1065,13 @@ CLASS lcl_log DEFINITION FINAL. show. PRIVATE SECTION. - DATA: mt_log TYPE rs_t_msg. + TYPES: BEGIN OF ty_log, + msg TYPE string, + type TYPE symsgty, + rc TYPE balsort, + END OF ty_log. + + DATA: mt_log TYPE STANDARD TABLE OF ty_log WITH DEFAULT KEY. ENDCLASS. @@ -1076,9 +1079,8 @@ CLASS lcl_log IMPLEMENTATION. METHOD to_html. - DATA: lv_class TYPE string, - lv_icon TYPE string, - lv_string TYPE string. + DATA: lv_class TYPE string, + lv_icon TYPE string. FIELD-SYMBOLS: LIKE LINE OF mt_log. @@ -1089,7 +1091,7 @@ CLASS lcl_log IMPLEMENTATION. ENDIF. LOOP AT mt_log ASSIGNING . - CASE -msgty. + CASE -type. WHEN 'W'. lv_icon = 'alert'. lv_class = 'warning'. @@ -1101,12 +1103,9 @@ CLASS lcl_log IMPLEMENTATION. lv_class = 'error'. ENDCASE. - CONCATENATE -msgv1 -msgv2 -msgv3 -msgv4 - INTO lv_string SEPARATED BY space. - ro_html->add( || ). ro_html->add_icon( iv_name = lv_icon ). - ro_html->add( lv_string ). + ro_html->add( -msg ). ro_html->add( '' ). ENDLOOP. @@ -1117,26 +1116,35 @@ CLASS lcl_log IMPLEMENTATION. FIELD-SYMBOLS: LIKE LINE OF mt_log. APPEND INITIAL LINE TO mt_log ASSIGNING . - -msgty = iv_msgty. " Error by default - -msgid = '00'. - -msgno = '001'. - -msgv1 = iv_msgv1. - -msgv2 = iv_msgv2. - -msgv3 = iv_msgv3. - -msgv4 = iv_msgv4. - -alsort = iv_rc. " Error code for unit test, not sure about better field + -msg = iv_msg. + -type = iv_type. + -rc = iv_rc. ENDMETHOD. METHOD show. - CALL FUNCTION 'RSDC_SHOW_MESSAGES_POPUP' +* only supports showing 4 errors, but I guess this is okay +* alternatively refactor to use method TO_HTML instead + + DATA: ls_log1 LIKE LINE OF mt_log, + ls_log2 LIKE LINE OF mt_log, + ls_log3 LIKE LINE OF mt_log, + ls_log4 LIKE LINE OF mt_log. + + + READ TABLE mt_log INDEX 1 INTO ls_log1. + READ TABLE mt_log INDEX 1 INTO ls_log2. + READ TABLE mt_log INDEX 1 INTO ls_log3. + READ TABLE mt_log INDEX 1 INTO ls_log4. + + CALL FUNCTION 'POPUP_TO_INFORM' EXPORTING - i_t_msg = mt_log - i_txt = 'Warning' - i_with_s_on_empty = abap_false - i_one_msg_direct = abap_false - i_one_msg_type_s = abap_false - ##no_text. + titel = 'Log' + txt1 = ls_log1-msg + txt2 = ls_log2-msg + txt3 = ls_log3-msg + txt4 = ls_log4-msg. + ENDMETHOD. METHOD count. @@ -1148,7 +1156,7 @@ CLASS lcl_log IMPLEMENTATION. ENDMETHOD. " clear. METHOD has_rc. - READ TABLE mt_log WITH KEY alsort = iv_rc TRANSPORTING NO FIELDS. + READ TABLE mt_log WITH KEY rc = iv_rc TRANSPORTING NO FIELDS. rv_yes = boolc( sy-subrc = 0 ). ENDMETHOD. "has_rc From 63a71f15fbd06ba7ae74c907c0a5f4cbe285f26e Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sat, 4 Mar 2017 08:15:30 +0200 Subject: [PATCH 18/28] page_diff UX filter part1 --- src/zabapgit_css_common.w3mi.data.css | 10 ++++ src/zabapgit_html.prog.abap | 21 ++++--- src/zabapgit_js_common.w3mi.data.js | 57 ++++++++++++++++++ src/zabapgit_page_diff.prog.abap | 84 ++++++++++++++++++++++++--- src/zabapgit_page_main.prog.abap | 1 - 5 files changed, 158 insertions(+), 15 deletions(-) diff --git a/src/zabapgit_css_common.w3mi.data.css b/src/zabapgit_css_common.w3mi.data.css index 31365ec0b..bf8118068 100644 --- a/src/zabapgit_css_common.w3mi.data.css +++ b/src/zabapgit_css_common.w3mi.data.css @@ -457,6 +457,16 @@ span.diff_name { padding-left: 0.5em; color: grey; } +span.diff_changed_by { + color: grey; + float: right; +} +span.diff_changed_by span.user { + border-radius: 3px; + border: solid 1px #c2d4ea; + background-color: #d9e4f2; + padding: 1px 0.4em; +} span.diff_name strong { color: #333; } diff --git a/src/zabapgit_html.prog.abap b/src/zabapgit_html.prog.abap index cba8b08e3..6c727461d 100644 --- a/src/zabapgit_html.prog.abap +++ b/src/zabapgit_html.prog.abap @@ -388,7 +388,6 @@ CLASS lcl_html_toolbar DEFINITION FINAL. iv_vertical TYPE abap_bool OPTIONAL iv_sort TYPE abap_bool OPTIONAL iv_as_angle TYPE abap_bool OPTIONAL - iv_with_icons TYPE abap_bool OPTIONAL iv_add_minizone TYPE abap_bool OPTIONAL RETURNING VALUE(ro_html) TYPE REF TO lcl_html. @@ -435,8 +434,9 @@ CLASS lcl_html_toolbar IMPLEMENTATION. METHOD render. "TODO refactor - DATA: lv_class TYPE string, - lv_is_drop TYPE abap_bool. + DATA: lv_class TYPE string, + lv_has_icons TYPE abap_bool, + lv_is_drop TYPE abap_bool. FIELD-SYMBOLS LIKE LINE OF mt_items. @@ -479,15 +479,22 @@ CLASS lcl_html_toolbar IMPLEMENTATION. SORT mt_items BY txt ASCENDING AS TEXT. ENDIF. - IF iv_with_icons = abap_true. + " Check has icons + LOOP AT mt_items ASSIGNING WHERE ico IS NOT INITIAL. + lv_has_icons = abap_true. + EXIT. + ENDLOOP. + + IF lv_has_icons = abap_true. ro_html->add( '' ). ENDIF. + " Render items LOOP AT mt_items ASSIGNING . IF -sub IS INITIAL. - IF iv_with_icons = abap_true. + IF lv_has_icons = abap_true. ro_html->add( '' ). ro_html->add( || ). ro_html->add( '' ). ro_html->add( '' ). ENDIF. @@ -509,7 +516,7 @@ CLASS lcl_html_toolbar IMPLEMENTATION. ENDLOOP. - IF iv_with_icons = abap_true. + IF lv_has_icons = abap_true. ro_html->add( '
{ lcl_html=>icon( -ico ) }' ). @@ -498,7 +505,7 @@ CLASS lcl_html_toolbar IMPLEMENTATION. iv_opt = -opt iv_typ = -typ ). - IF iv_with_icons = abap_true. + IF lv_has_icons = abap_true. ro_html->add( '
' ). ENDIF. diff --git a/src/zabapgit_js_common.w3mi.data.js b/src/zabapgit_js_common.w3mi.data.js index f37db91d9..9bc8dbbe2 100644 --- a/src/zabapgit_js_common.w3mi.data.js +++ b/src/zabapgit_js_common.w3mi.data.js @@ -363,3 +363,60 @@ StageHelper.prototype.iterateStageTab = function (changeMode, cb /*, ...*/) { window.scrollTo(0, scrollOffset); } } + +/********************************************************** + * Diff page logic + **********************************************************/ + +function diffProcessFilterClick(e) { + var target = event.target || event.srcElement; + + if (!target) return; + if (target.tagName !== "A") return; + if (target.parentNode.tagName !== "TD") return; + + var iconTd = target.parentNode.parentNode.children[0]; + + if (!iconTd) return; + if (iconTd.tagName !== "TD") return; + + var icon = iconTd.firstChild; + if (icon.tagName !== "I") return; + if (!icon.classList.contains("octicon")) return; + + var state; + if (icon.classList.contains("blue")) { + icon.classList.remove("blue"); + icon.classList.add("grey"); + state = false; + } else { + icon.classList.add("blue"); + icon.classList.remove("grey"); + state = true; + } + + return { filter: target.innerText, state: state }; +} + +function diffApplyFilter(param, action) { + var diffList = document.getElementById("diff-list"); + // console.log("Action:", param, action.filter, action.state); + for (var i = diffList.children.length - 1; i >= 0; i--) { + var div = diffList.children[i]; + if (div.className !== "diff") return; // Unexpected error ! + var attr = div.getAttribute("data-"+param); + if (attr === action.filter) { + div.style.display = action.state ? "" : "none"; + } + } +} + +function diffFilterType(e) { + var action = diffProcessFilterClick(e); + diffApplyFilter("type", action); +} + +function diffFilterUser(e) { + var action = diffProcessFilterClick(e); + diffApplyFilter("changed-by", action); +} diff --git a/src/zabapgit_page_diff.prog.abap b/src/zabapgit_page_diff.prog.abap index 29e79a0a1..51b3d61df 100644 --- a/src/zabapgit_page_diff.prog.abap +++ b/src/zabapgit_page_diff.prog.abap @@ -14,11 +14,13 @@ CLASS lcl_gui_page_diff DEFINITION FINAL INHERITING FROM lcl_gui_page. END OF c_fstate. TYPES: BEGIN OF ty_file_diff, - filename TYPE string, - lstate TYPE char1, - rstate TYPE char1, - fstate TYPE char1, " FILE state - Abstraction for shorter ifs - o_diff TYPE REF TO lcl_diff, + filename TYPE string, + lstate TYPE char1, + rstate TYPE char1, + fstate TYPE char1, " FILE state - Abstraction for shorter ifs + o_diff TYPE REF TO lcl_diff, + changed_by TYPE xubname, + type TYPE string, END OF ty_file_diff, tt_file_diff TYPE STANDARD TABLE OF ty_file_diff. @@ -87,7 +89,6 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. super->constructor( ). ms_control-page_title = 'DIFF'. - ms_control-page_menu = build_menu( ). mv_unified = lcl_app=>user( )->get_diff_unified( ). ASSERT is_file IS INITIAL OR is_object IS INITIAL. " just one passed @@ -131,11 +132,14 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. lcx_exception=>raise( 'PAGE_DIFF ERROR: No diff files found' ). ENDIF. + ms_control-page_menu = build_menu( ). + ENDMETHOD. METHOD append_diff. DATA: + lv_offs TYPE i, ls_r_dummy LIKE LINE OF it_remote ##NEEDED, ls_l_dummy LIKE LINE OF it_local ##NEEDED. @@ -175,6 +179,24 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. -fstate = c_fstate-remote. ENDIF. + " Changed by + IF -item-obj_type IS NOT INITIAL. + -changed_by = to_lower( lcl_objects=>changed_by( -item ) ). + ENDIF. + + " Extension + IF -file-filename IS NOT INITIAL. + -type = reverse( -file-filename ). + ELSE. + -type = reverse( -filename ). + ENDIF. + + FIND FIRST OCCURRENCE OF '.' IN -type MATCH OFFSET lv_offs. + -type = reverse( substring( val = -type len = lv_offs ) ). + IF -type <> 'xml' AND -type <> 'abap'. + -type = 'other'. + ENDIF. + IF -fstate = c_fstate-remote. " Remote file leading changes CREATE OBJECT -o_diff EXPORTING @@ -190,9 +212,51 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. ENDMETHOD. "append_diff METHOD build_menu. + + DATA: lo_sub TYPE REF TO lcl_html_toolbar, + lt_types TYPE string_table, + lt_users TYPE string_table. + + FIELD-SYMBOLS: LIKE LINE OF mt_diff_files, + TYPE string. + + LOOP AT mt_diff_files ASSIGNING . + APPEND -type TO lt_types. + APPEND -changed_by TO lt_users. + ENDLOOP. + + SORT: lt_types, lt_users. + DELETE ADJACENT DUPLICATES FROM: lt_types, lt_users. + CREATE OBJECT ro_menu. + + IF lines( lt_types ) > 1. + CREATE OBJECT lo_sub. + LOOP AT lt_types ASSIGNING . + lo_sub->add( iv_txt = + iv_typ = gc_action_type-onclick + iv_ico = 'check/blue' + iv_act = 'diffFilterType(event);' ). + ENDLOOP. + ro_menu->add( iv_txt = 'Filter type' + io_sub = lo_sub ) ##NO_TEXT. + ENDIF. + + IF lines( lt_users ) > 1. + CREATE OBJECT lo_sub. + LOOP AT lt_users ASSIGNING . + lo_sub->add( iv_txt = + iv_typ = gc_action_type-onclick + iv_ico = 'check/blue' + iv_act = 'diffFilterUser(event);' ). + ENDLOOP. + ro_menu->add( iv_txt = 'Filter user' + io_sub = lo_sub ) ##NO_TEXT. + ENDIF. + ro_menu->add( iv_txt = 'Split/Unified view' iv_act = c_actions-toggle_unified ) ##NO_TEXT. + ENDMETHOD. " build_menu. ********************************************************************** @@ -219,6 +283,7 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. CREATE OBJECT ro_html. + ro_html->add( '
' ). LOOP AT mt_diff_files INTO ls_diff_file. lcl_progress=>show( iv_key = 'Diff' iv_current = sy-tabix @@ -227,6 +292,7 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. ro_html->add( render_diff( ls_diff_file ) ). ENDLOOP. + ro_html->add( '
' ). ENDMETHOD. "render_content @@ -234,7 +300,8 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. CREATE OBJECT ro_html. - ro_html->add( '
' ). "#EC NOTEXT + ro_html->add( |
| ). "#EC NOTEXT ro_html->add( render_diff_head( is_diff ) ). " Content @@ -279,6 +346,9 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. && ' highlighting for MM assumes local file is newer ! ' ). "#EC NOTEXT ENDIF. + ro_html->add( |last change by: { + is_diff-changed_by }| ). + ro_html->add( '
' ). "#EC NOTEXT ENDMETHOD. diff --git a/src/zabapgit_page_main.prog.abap b/src/zabapgit_page_main.prog.abap index 63adfaad4..c60e9daa2 100644 --- a/src/zabapgit_page_main.prog.abap +++ b/src/zabapgit_page_main.prog.abap @@ -292,7 +292,6 @@ CLASS lcl_gui_page_main IMPLEMENTATION. ro_html->add( lo_allbar->render( iv_as_droplist_with_label = lcl_html=>icon( iv_name = 'three-bars/blue' iv_class = 'pad4px' ) iv_sort = abap_true - iv_with_icons = abap_true iv_add_minizone = abap_true ) ). ro_html->add( '' ). ro_html->add( '' ). From f3c496cd2fe4fb2cc256d5c71a338c0d90be7ff1 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sat, 4 Mar 2017 21:54:37 +0200 Subject: [PATCH 19/28] toolbar refactoring part1 --- src/zabapgit_css_common.w3mi.data.css | 137 ++++++++++++++-- src/zabapgit_definitions.prog.abap | 8 +- src/zabapgit_html.prog.abap | 222 ++++++++++++++++---------- src/zabapgit_page.prog.abap | 2 +- src/zabapgit_page_db.prog.abap | 2 +- src/zabapgit_page_main.prog.abap | 23 ++- src/zabapgit_view_repo.prog.abap | 4 +- 7 files changed, 275 insertions(+), 123 deletions(-) diff --git a/src/zabapgit_css_common.w3mi.data.css b/src/zabapgit_css_common.w3mi.data.css index bf8118068..62e215bbc 100644 --- a/src/zabapgit_css_common.w3mi.data.css +++ b/src/zabapgit_css_common.w3mi.data.css @@ -55,30 +55,21 @@ input:focus, textarea:focus { .w40 { width: 40%; } /* STRUCTURE DIVS, HEADER & FOOTER */ -td.headpad { padding-top: 11px; } -td.logo { width: 164px; } - div#header { padding: 0.5em 0.5em; border-bottom: 3px double lightgrey; } +div#header td.headpad { padding-top: 11px; } +div#header td.logo { width: 164px; } div#toc { padding: 0.5em 1em; background-color: #f2f2f2; } -div#toc div.toc_grid { - margin: -0.3em 0em; -} - -div#toc div.toc_grid a { - color: #ccc; -} - -div#toc:hover div.toc_grid a { - color: #4078c0; -} +div#toc div.toc_grid { margin: -0.3em 0em; } +div#toc .favorites a { opacity: 0.5; } +div#toc .favorites:hover a { opacity: 1; } div#toc div.toc_row { margin: 0.3em 0em; @@ -184,15 +175,15 @@ div.menu_vertical a { position: absolute; padding: 0px; width: 16px; - height: 16px; + height: 100%; bottom: 0px; - left: -16px; + right: 100%; } +.dropdown:hover .minizone { display: block; } .dropdown_angle .dropdown_content { top: -1px; } .dropdown:hover .dropdown_content { display: block; } -.dropdown:hover .minizone { display: block; } .dropdown_content a { padding: 0.2em; background-color: #f9f9f9; @@ -710,3 +701,115 @@ div.tutorial h2 { font-size: 14pt; color: #404040; } + +/* NEW MENU */ + +.nav-container ul +{ + list-style: none; + position: relative; + float: left; + margin: 0; + padding: 0; + /*text-align: left;*/ +} + +.nav-container.float-right ul { + float: right; + /*text-align: right;*/ +} + +.nav-container ul a +{ + display: block; + color: #444; + text-decoration: none; + font-size: 11pt; + line-height: 30px; + padding: 0 12px; +} + +.nav-container ul li +{ + position: relative; + float: left; + margin: 0; + padding: 0; +} + +.nav-container ul li.current-menu-item +{ + font-weight: 700; +} + +.nav-container ul ul li:hover +{ + background: #f6f6f6; + /*color: #8cadd9;*/ +} + +.nav-container ul li:hover > a +{ + /*color: #8cadd9;*/ + color: #6692cc; +} + +.nav-container ul ul +{ + display: none; + position: absolute; + top: 100%; + left: 0; + z-index: 1; + background: #fff; + padding: 0; + box-shadow: 1px 1px 3px 0px #bbb; +} + +.nav-container.float-right ul ul { + left: auto; + right: 0; +} + +.nav-container ul ul li +{ + float: none; + min-width: 160px; +} + +.nav-container ul ul a +{ + line-height: 120%; + padding: 8px 15px; +} + +.nav-container ul ul ul +{ + top: 0; + left: 100%; +} + +.nav-container ul li:hover > ul +{ + display: block; +} + +.nav-container > ul > li > div.minizone { + display: none; + z-index: 1; + position: absolute; + padding: 0px; + width: 16px; + height: 100%; + bottom: 0px; + left: 100%; +} +.nav-container > ul > li:hover div.minizone { display: block; } +.nav-container.float-right > ul > li > div.minizone { + left: auto; + right: 100%; +} + +.nav-container li a .octicon { + padding-right: 12px; +} diff --git a/src/zabapgit_definitions.prog.abap b/src/zabapgit_definitions.prog.abap index a1edf8f5d..9861d3d46 100644 --- a/src/zabapgit_definitions.prog.abap +++ b/src/zabapgit_definitions.prog.abap @@ -172,9 +172,11 @@ CONSTANTS: BEGIN OF gc_html_opt, END OF gc_html_opt. CONSTANTS: BEGIN OF gc_action_type, - sapevent TYPE c VALUE 'E', - url TYPE c VALUE 'U', - onclick TYPE c VALUE 'C', + sapevent TYPE c VALUE 'E', + url TYPE c VALUE 'U', + onclick TYPE c VALUE 'C', + separator TYPE c VALUE 'S', + dummy TYPE c VALUE '_', END OF gc_action_type. CONSTANTS: gc_newline TYPE abap_char1 VALUE cl_abap_char_utilities=>newline. diff --git a/src/zabapgit_html.prog.abap b/src/zabapgit_html.prog.abap index 6c727461d..48086a310 100644 --- a/src/zabapgit_html.prog.abap +++ b/src/zabapgit_html.prog.abap @@ -288,6 +288,7 @@ CLASS lcl_html IMPLEMENTATION. DATA: lv_class TYPE string, lv_href TYPE string, + lv_click TYPE string, lv_id TYPE string, lv_style TYPE string. @@ -307,14 +308,18 @@ CLASS lcl_html IMPLEMENTATION. lv_class = | class="{ lv_class }"|. ENDIF. - IF iv_act IS NOT INITIAL. + lv_href = ' href="#"'. " Default, dummy + IF iv_act IS NOT INITIAL OR iv_typ = gc_action_type-dummy. CASE iv_typ. WHEN gc_action_type-url. - lv_href = | href="{ iv_act }"|. + lv_href = | href="{ iv_act }"|. WHEN gc_action_type-sapevent. - lv_href = | href="sapevent:{ iv_act }"|. + lv_href = | href="sapevent:{ iv_act }"|. WHEN gc_action_type-onclick. - lv_href = | onclick="{ iv_act }"|. + lv_href = ' href="#"'. + lv_click = | onclick="{ iv_act }"|. + WHEN gc_action_type-dummy. + lv_href = ' href="#"'. ENDCASE. ENDIF. @@ -326,7 +331,7 @@ CLASS lcl_html IMPLEMENTATION. lv_style = | style="{ iv_style }"|. ENDIF. - rv_str = |{ iv_txt }|. + rv_str = |{ iv_txt }|. ENDMETHOD. "a @@ -375,37 +380,51 @@ CLASS lcl_html_toolbar DEFINITION FINAL. IMPORTING iv_txt TYPE string io_sub TYPE REF TO lcl_html_toolbar OPTIONAL + iv_typ TYPE c DEFAULT gc_action_type-sapevent iv_act TYPE string OPTIONAL iv_ico TYPE string OPTIONAL - iv_opt TYPE c OPTIONAL - iv_typ TYPE c DEFAULT gc_action_type-sapevent, + iv_cur TYPE abap_bool OPTIONAL + iv_opt TYPE c OPTIONAL, count RETURNING VALUE(rv_count) TYPE i, render IMPORTING - iv_as_droplist_with_label TYPE string OPTIONAL - iv_no_separator TYPE abap_bool OPTIONAL - iv_vertical TYPE abap_bool OPTIONAL + iv_right TYPE abap_bool OPTIONAL iv_sort TYPE abap_bool OPTIONAL - iv_as_angle TYPE abap_bool OPTIONAL - iv_add_minizone TYPE abap_bool OPTIONAL RETURNING - VALUE(ro_html) TYPE REF TO lcl_html. + VALUE(ro_html) TYPE REF TO lcl_html, + render_as_droplist + IMPORTING + iv_label TYPE string + iv_right TYPE abap_bool OPTIONAL + iv_sort TYPE abap_bool OPTIONAL + iv_as_angle TYPE abap_bool OPTIONAL + RETURNING + VALUE(ro_html) TYPE REF TO lcl_html. PRIVATE SECTION. - TYPES: BEGIN OF ty_item, - txt TYPE string, - act TYPE string, - ico TYPE string, - sub TYPE REF TO lcl_html_toolbar, - opt TYPE char1, - typ TYPE char1, - END OF ty_item. + TYPES: + BEGIN OF ty_item, + txt TYPE string, + act TYPE string, + ico TYPE string, + sub TYPE REF TO lcl_html_toolbar, + opt TYPE char1, + typ TYPE char1, + cur TYPE abap_bool, + END OF ty_item. TYPES tt_items TYPE STANDARD TABLE OF ty_item. DATA mt_items TYPE tt_items. + METHODS + render_items + IMPORTING + iv_sort TYPE abap_bool OPTIONAL + RETURNING + VALUE(ro_html) TYPE REF TO lcl_html. + ENDCLASS. "lcl_html_toolbar DEFINITION *----------------------------------------------------------------------* @@ -420,8 +439,11 @@ CLASS lcl_html_toolbar IMPLEMENTATION. METHOD add. DATA ls_item TYPE ty_item. - ASSERT iv_act IS INITIAL AND io_sub IS NOT INITIAL - OR iv_act IS NOT INITIAL AND io_sub IS INITIAL. " Only one supplied + ASSERT iv_typ = gc_action_type-separator " sep doesn't have action + OR iv_typ = gc_action_type-onclick " click may have no action (assigned in JS) + OR iv_typ = gc_action_type-dummy " dummy may have no action + OR iv_act IS INITIAL AND io_sub IS NOT INITIAL + OR iv_act IS NOT INITIAL AND io_sub IS INITIAL. " Only one supplied ls_item-txt = iv_txt. ls_item-act = iv_act. @@ -429,104 +451,130 @@ CLASS lcl_html_toolbar IMPLEMENTATION. ls_item-sub = io_sub. ls_item-opt = iv_opt. ls_item-typ = iv_typ. + ls_item-cur = iv_cur. APPEND ls_item TO mt_items. + ENDMETHOD. "add - METHOD render. "TODO refactor - - DATA: lv_class TYPE string, - lv_has_icons TYPE abap_bool, - lv_is_drop TYPE abap_bool. - - FIELD-SYMBOLS LIKE LINE OF mt_items. + METHOD render. + DATA: lv_class TYPE string. CREATE OBJECT ro_html. - lv_is_drop = boolc( iv_as_droplist_with_label IS NOT INITIAL OR iv_as_angle IS NOT INITIAL ). - IF lv_is_drop = abap_false. " Normal menu - IF iv_vertical = abap_true. - lv_class = 'menu_vertical' ##NO_TEXT. - ELSE. - lv_class = 'menu' ##NO_TEXT. - ENDIF. - ELSEIF iv_as_angle IS NOT INITIAL. - lv_class = 'dropdown dropdown_angle' ##NO_TEXT. - ELSE. - lv_class = 'dropdown' ##NO_TEXT. + lv_class = 'nav-container' ##NO_TEXT. + IF iv_right = abap_true. + lv_class = lv_class && ' float-right'. ENDIF. ro_html->add( |
| ). + ro_html->add( render_items( iv_sort = iv_sort ) ). + ro_html->add( '
' ). - IF lv_is_drop = abap_true. " Dropdown - IF iv_as_angle = abap_true. - ro_html->add( '
' ). - ELSE. - ro_html->add_a( iv_txt = iv_as_droplist_with_label - iv_class = 'dropbtn' - iv_act = '' ). - ENDIF. + ENDMETHOD. "render - IF iv_add_minizone = abap_true. - ro_html->add( '
' ). - ENDIF. + METHOD render_as_droplist. - ro_html->add( '' ). - ENDIF. +* IF lv_has_icons = abap_true. +* ro_html->add( '' ). +* ENDIF. - ro_html->add( '
' ). + ENDMETHOD. "render_items - ENDMETHOD. "render ENDCLASS. "lcl_html_toolbar IMPLEMENTATION diff --git a/src/zabapgit_page.prog.abap b/src/zabapgit_page.prog.abap index c8be3f69c..f439c9e4c 100644 --- a/src/zabapgit_page.prog.abap +++ b/src/zabapgit_page.prog.abap @@ -100,7 +100,7 @@ CLASS lcl_gui_page IMPLEMENTATION. IF ms_control-page_menu IS BOUND. ro_html->add( '' ). "#EC NOTEXT - ro_html->add( ms_control-page_menu->render( ) ). + ro_html->add( ms_control-page_menu->render( iv_right = abap_true ) ). ro_html->add( '' ). "#EC NOTEXT ENDIF. diff --git a/src/zabapgit_page_db.prog.abap b/src/zabapgit_page_db.prog.abap index 677330be4..78a4c2e19 100644 --- a/src/zabapgit_page_db.prog.abap +++ b/src/zabapgit_page_db.prog.abap @@ -214,7 +214,7 @@ CLASS lcl_gui_page_db IMPLEMENTATION. ro_html->add( |{ -value }| ). ro_html->add( |{ explain_content( ) }| ). ro_html->add( '' ). - ro_html->add( lo_toolbar->render( iv_vertical = abap_false ) ). + ro_html->add( lo_toolbar->render( ) ). ro_html->add( '' ). ro_html->add( '' ). ENDLOOP. diff --git a/src/zabapgit_page_main.prog.abap b/src/zabapgit_page_main.prog.abap index c60e9daa2..3b0628436 100644 --- a/src/zabapgit_page_main.prog.abap +++ b/src/zabapgit_page_main.prog.abap @@ -209,7 +209,7 @@ CLASS lcl_gui_page_main IMPLEMENTATION. METHOD render_toc. DATA: lo_pback TYPE REF TO lcl_persistence_background, - lv_opt TYPE char1, + lv_cur TYPE abap_bool, lv_key TYPE lcl_persistence_repo=>ty_repo-key, lv_icon TYPE string, lo_repo LIKE LINE OF it_repo_list, @@ -228,10 +228,9 @@ CLASS lcl_gui_page_main IMPLEMENTATION. LOOP AT it_repo_list INTO lo_repo. lv_key = lo_repo->get_key( ). + lv_cur = abap_false. IF lv_key = mv_show. - lv_opt = gc_html_opt-strong. - ELSE. - CLEAR lv_opt. + lv_cur = abap_true. ENDIF. lv_repo_title = lo_repo->get_name( ). @@ -246,7 +245,7 @@ CLASS lcl_gui_page_main IMPLEMENTATION. DELETE lt_favorites INDEX sy-tabix. " for later cleanup lo_favbar->add( iv_txt = lv_repo_title iv_act = |{ c_actions-show }?{ lv_key }| - iv_opt = lv_opt ). + iv_cur = lv_cur ). ENDIF. IF lo_repo->is_offline( ) = abap_true. @@ -258,7 +257,7 @@ CLASS lcl_gui_page_main IMPLEMENTATION. lo_allbar->add( iv_txt = lv_repo_title iv_act = |{ c_actions-show }?{ lv_key }| iv_ico = lv_icon - iv_opt = lv_opt ). + iv_cur = lv_cur ). ENDLOOP. " Cleanup orphan favorites (for removed repos) @@ -278,7 +277,7 @@ CLASS lcl_gui_page_main IMPLEMENTATION. lcl_html=>icon( iv_name = 'star/blue' iv_alt = 'Favs' iv_hint = 'Favorites' ) }| ). - ro_html->add( '' ). " Maximize width + ro_html->add( '' ). " Maximize width IF lo_favbar->count( ) > 0. ro_html->add( lo_favbar->render( iv_sort = abap_true ) ). ELSE. @@ -288,11 +287,11 @@ CLASS lcl_gui_page_main IMPLEMENTATION. ENDIF. ro_html->add( '' ). - ro_html->add( '' ). - ro_html->add( lo_allbar->render( - iv_as_droplist_with_label = lcl_html=>icon( iv_name = 'three-bars/blue' iv_class = 'pad4px' ) - iv_sort = abap_true - iv_add_minizone = abap_true ) ). + ro_html->add( '' ). + ro_html->add( lo_allbar->render_as_droplist( + iv_label = lcl_html=>icon( iv_name = 'three-bars/blue' iv_class = 'pad4px' ) + iv_right = abap_true + iv_sort = abap_true ) ). ro_html->add( '' ). ro_html->add( '' ). diff --git a/src/zabapgit_view_repo.prog.abap b/src/zabapgit_view_repo.prog.abap index 9d91df8cc..582507829 100644 --- a/src/zabapgit_view_repo.prog.abap +++ b/src/zabapgit_view_repo.prog.abap @@ -240,7 +240,7 @@ CLASS lcl_gui_view_repo_content IMPLEMENTATION. lo_tab_menu->add( iv_txt = 'With folders' iv_act = c_actions-toggle_folders ). ENDIF. - ro_html = lo_tab_menu->render( iv_as_angle = abap_true ). + ro_html = lo_tab_menu->render_as_droplist( iv_label = 'SET' iv_as_angle = abap_true ). ENDMETHOD. "render_grid_menu @@ -356,7 +356,7 @@ CLASS lcl_gui_view_repo_content IMPLEMENTATION. ENDIF. ro_html->add( '' ). - ro_html->add( lo_toolbar->render( ) ). + ro_html->add( lo_toolbar->render( iv_right = abap_true ) ). ro_html->add( '' ). ro_html->add( '' ). ro_html->add( '' ). From ecdf53bf6d0c37236ee7238afa9b9d950f0440c5 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sun, 5 Mar 2017 21:15:38 +0200 Subject: [PATCH 20/28] toolbar refactoring part2 --- src/zabapgit_css_common.w3mi.data.css | 208 +++++++------------------- src/zabapgit_html.prog.abap | 33 +--- src/zabapgit_page.prog.abap | 4 +- src/zabapgit_page_db.prog.abap | 63 ++++---- src/zabapgit_page_main.prog.abap | 14 +- src/zabapgit_view_repo.prog.abap | 5 +- 6 files changed, 107 insertions(+), 220 deletions(-) diff --git a/src/zabapgit_css_common.w3mi.data.css b/src/zabapgit_css_common.w3mi.data.css index 62e215bbc..4213deeff 100644 --- a/src/zabapgit_css_common.w3mi.data.css +++ b/src/zabapgit_css_common.w3mi.data.css @@ -59,45 +59,45 @@ div#header { padding: 0.5em 0.5em; border-bottom: 3px double lightgrey; } -div#header td.headpad { padding-top: 11px; } -div#header td.logo { width: 164px; } +div#header td.logo { width: 164px; } +div#header td:not(.logo) { padding-top: 11px; } /* align with logo H */ +div#header span.page_title { + font-weight: normal; + font-size: 18pt; + color: #bbb; + padding-left: 0.4em; +} div#toc { padding: 0.5em 1em; background-color: #f2f2f2; } - -div#toc div.toc_grid { margin: -0.3em 0em; } div#toc .favorites a { opacity: 0.5; } div#toc .favorites:hover a { opacity: 1; } -div#toc div.toc_row { - margin: 0.3em 0em; -} - div#footer { padding: 0.5em 1em; border-top: 3px double lightgrey; text-align: center; } - -div.dummydiv { - background-color: #f2f2f2; - padding: 0.5em 1em; - text-align: center; -} - -span.version { +div#footer span.version { display: block; color: grey; margin-top: 0.3em; } -span.page_title { - font-weight: normal; - font-size: 18pt; - color: #bbb; - padding-left: 0.4em; +#debug-output { + text-align: right; + padding-right: 0.5em; + color: #ccc; + font-style: italic; + font-size: small; +} + +div.dummydiv { + background-color: #f2f2f2; + padding: 0.5em 1em; + text-align: center; } /* ERROR LOG */ @@ -109,101 +109,9 @@ div.log { border: 1px #fdcece solid; border-radius: 4px; } - div.log > span { display:block; } div.log .octicon { padding-right: 6px; } -/* MENU */ -div.menu { display: inline; } -div.menu .menu_end { border-right: 0px !important; } -div.menu a { - padding-left: 0.5em; - padding-right: 0.5em; - font-size: 12pt; -} - -div.menu > a { - border-right: 1px solid lightgrey; -} -div.menu > div.dropdown > a { - border-right: 1px solid lightgrey; -} -div.menu > a:last-child { - border-right: 0px !important; -} -div.menu > div.dropdown:last-child > a { - border-right: 0px !important; -} - -div.menu_vertical { display: inline; } -div.menu_vertical a { - display: block; - font-size: 12pt; -} - -/*DROP DOWN*/ -.dropdown { - position: relative; - display: inline; -} -.dropdown_angle { - position: absolute !important; - right: -4px; - top: -1px; -} -.dropbtn_angle { - width: 0; - height: 0; - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-bottom: 7px solid #4078c0; - transform: rotate(45deg); - -ms-transform: rotate(45deg); -} -.dropdown_content { - display: none; - z-index: 1; - position: absolute; - right: -12px; - top: 1em; - padding: 6px 10px 10px 10px; - white-space: nowrap; -} -.dropdown div.minizone { - display: none; - z-index: 1; - position: absolute; - padding: 0px; - width: 16px; - height: 100%; - bottom: 0px; - right: 100%; -} -.dropdown:hover .minizone { display: block; } -.dropdown_angle .dropdown_content { - top: -1px; -} -.dropdown:hover .dropdown_content { display: block; } -.dropdown_content a { - padding: 0.2em; - background-color: #f9f9f9; - text-decoration: none; - display: block; - border: none !important; -} -.dropdown_content div.box { - border-bottom: 1px solid #C0C0C0; - border-right: 1px solid #C0C0C0; - background-color: #f9f9f9; - padding: 2px; -} -.dropdown_content td { text-align: left; padding: 2px; } -.dropdown_content td a { padding: 0em 0.2em; } -.dropdown_content td.icon { padding: 0 3px 0 6px; } -.dropdown_content td.text { width: 100%; } -.dropdown_content a:hover { background-color: #f1f1f1 } -.dropdown:hover .dropbtn { color: #79a0d2; } - /* REPOSITORY */ div.repo { margin-top: 3px; @@ -265,14 +173,6 @@ div.repo { overflow: hidden; } -#debug-output { - text-align: right; - padding-right: 0.5em; - color: #ccc; - font-style: italic; - font-size: small; -} - /* REPOSITORY TABLE*/ div.repo_container { position: relative; @@ -703,7 +603,9 @@ div.tutorial h2 { } /* NEW MENU */ - +/* Special credits to example at https://codepen.io/philhoyt/pen/ujHzd */ +/* container div, aligned left, + but with .float-right modifier alignes right */ .nav-container ul { list-style: none; @@ -711,24 +613,20 @@ div.tutorial h2 { float: left; margin: 0; padding: 0; - /*text-align: left;*/ -} - -.nav-container.float-right ul { - float: right; - /*text-align: right;*/ } +.nav-container.float-right ul { float: right; } .nav-container ul a { display: block; - color: #444; text-decoration: none; font-size: 11pt; line-height: 30px; padding: 0 12px; } +/* submenues align to left or right border of the active item + depending on .float-right modifier */ .nav-container ul li { position: relative; @@ -736,22 +634,15 @@ div.tutorial h2 { margin: 0; padding: 0; } +.nav-container.float-right ul ul { left: auto; right: 0; } -.nav-container ul li.current-menu-item -{ - font-weight: 700; -} +.nav-container ul li.current-menu-item { font-weight: 700; } +.nav-container ul li:hover > ul { display: block; } +.nav-container ul ul li:hover { background-color: #f6f6f6; } -.nav-container ul ul li:hover -{ - background: #f6f6f6; - /*color: #8cadd9;*/ -} - -.nav-container ul li:hover > a -{ - /*color: #8cadd9;*/ - color: #6692cc; +/* special selection style for 1st level items (see also .corner below) */ +.nav-container > ul > li:hover > a { + background-color: rgba(255, 255, 255, 0.5); } .nav-container ul ul @@ -766,11 +657,6 @@ div.tutorial h2 { box-shadow: 1px 1px 3px 0px #bbb; } -.nav-container.float-right ul ul { - left: auto; - right: 0; -} - .nav-container ul ul li { float: none; @@ -789,11 +675,9 @@ div.tutorial h2 { left: 100%; } -.nav-container ul li:hover > ul -{ - display: block; -} - +/* Minizone to extent hover area, + aligned to the left or to the right of the selected item + depending on .float-right modifier */ .nav-container > ul > li > div.minizone { display: none; z-index: 1; @@ -810,6 +694,22 @@ div.tutorial h2 { right: 100%; } -.nav-container li a .octicon { +/* icons - text-align strictly left - otherwise look ugly + + bite a bit of left padding for nicer look + + forbids item text wrapping (maybe can be done differently) */ +.nav-container ul ul li a .octicon { padding-right: 12px; + margin-left: -3px; } +.nav-container ul.with-icons li { + text-align: left; + white-space: nowrap; +} + +/* Special .corner modifier - hangs menu at the top right corner + and cancels 1st level background coloring */ +.nav-container.corner { + position: absolute; + right: 0px; +} +.nav-container.corner > ul > li:hover > a { background-color: inherit; } diff --git a/src/zabapgit_html.prog.abap b/src/zabapgit_html.prog.abap index 48086a310..10d2cf1d4 100644 --- a/src/zabapgit_html.prog.abap +++ b/src/zabapgit_html.prog.abap @@ -398,7 +398,7 @@ CLASS lcl_html_toolbar DEFINITION FINAL. iv_label TYPE string iv_right TYPE abap_bool OPTIONAL iv_sort TYPE abap_bool OPTIONAL - iv_as_angle TYPE abap_bool OPTIONAL + iv_corner TYPE abap_bool OPTIONAL RETURNING VALUE(ro_html) TYPE REF TO lcl_html. @@ -479,15 +479,13 @@ CLASS lcl_html_toolbar IMPLEMENTATION. CREATE OBJECT ro_html. -* IF iv_as_angle IS NOT INITIAL. -* lv_class = 'dropdown dropdown_angle' ##NO_TEXT. -* ELSE. -* ENDIF. - lv_class = 'nav-container' ##NO_TEXT. IF iv_right = abap_true. lv_class = lv_class && ' float-right'. ENDIF. + IF iv_corner = abap_true. + lv_class = lv_class && ' corner'. + ENDIF. ro_html->add( |
| ). ro_html->add( '
  • ' ). @@ -518,25 +516,16 @@ CLASS lcl_html_toolbar IMPLEMENTATION. " Check has icons LOOP AT mt_items ASSIGNING WHERE ico IS NOT INITIAL. lv_has_icons = abap_true. + lv_class = ' class="with-icons"'. EXIT. ENDLOOP. -* IF lv_has_icons = abap_true. -* ro_html->add( '' ). -* ENDIF. - - ro_html->add( '
      ' ). + ro_html->add( || ). " Render items LOOP AT mt_items ASSIGNING . CLEAR: lv_class, lv_icon. -* IF lv_has_icons = abap_true. -* ro_html->add( '
    ' ). -* ro_html->add( || ). -* ro_html->add( '' ). -* ro_html->add( '' ). -* ENDIF. - - ENDLOOP. ro_html->add( '' ). -* IF lv_has_icons = abap_true. -* ro_html->add( '
    { lcl_html=>icon( -ico ) }' ). -* ENDIF. - IF lv_has_icons = abap_true. lv_icon = lcl_html=>icon( -ico ). ENDIF. @@ -560,20 +549,10 @@ CLASS lcl_html_toolbar IMPLEMENTATION. ENDIF. ro_html->add( '' ). -* IF lv_has_icons = abap_true. -* ro_html->add( '
    ' ). -* ENDIF. - ENDMETHOD. "render_items diff --git a/src/zabapgit_page.prog.abap b/src/zabapgit_page.prog.abap index f439c9e4c..79070db39 100644 --- a/src/zabapgit_page.prog.abap +++ b/src/zabapgit_page.prog.abap @@ -94,12 +94,12 @@ CLASS lcl_gui_page IMPLEMENTATION. iv_act = gc_action-abapgit_home ) }| ). "#EC NOTEXT - ro_html->add( | ► { + ro_html->add( | ► { ms_control-page_title }| ). "#EC NOTEXT IF ms_control-page_menu IS BOUND. - ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT ro_html->add( ms_control-page_menu->render( iv_right = abap_true ) ). ro_html->add( '' ). "#EC NOTEXT ENDIF. diff --git a/src/zabapgit_page_db.prog.abap b/src/zabapgit_page_db.prog.abap index 78a4c2e19..f4ba4850b 100644 --- a/src/zabapgit_page_db.prog.abap +++ b/src/zabapgit_page_db.prog.abap @@ -8,6 +8,10 @@ CLASS lcl_gui_page_db_display DEFINITION FINAL INHERITING FROM lcl_gui_page. METHODS: constructor IMPORTING is_key TYPE lcl_persistence_db=>ty_content. + CLASS-METHODS: render_record_banner + IMPORTING is_key TYPE lcl_persistence_db=>ty_content + RETURNING VALUE(rv_html) TYPE string. + PROTECTED SECTION. METHODS render_content REDEFINITION. @@ -24,10 +28,19 @@ CLASS lcl_gui_page_db_display IMPLEMENTATION. ms_control-page_title = 'CONFIG DISPLAY'. ENDMETHOD. + METHOD render_record_banner. + rv_html = || + && |
    Type:{ is_key-type }
    | + && gc_newline + && || + && |
    Key:{ is_key-value }
    |. + ENDMETHOD. "render_record_banner + METHOD render_content. DATA: lo_highlighter TYPE REF TO lcl_syntax_highlighter, + lo_toolbar TYPE REF TO lcl_html_toolbar, lv_data TYPE lcl_persistence_db=>ty_content-data_str, ls_action TYPE lcl_persistence_db=>ty_content, lv_action TYPE string. @@ -48,17 +61,15 @@ CLASS lcl_gui_page_db_display IMPLEMENTATION. lv_data = lo_highlighter->process_line( lcl_xml_pretty=>print( lv_data ) ). CREATE OBJECT ro_html. + CREATE OBJECT lo_toolbar. + lo_toolbar->add( iv_act = |{ gc_action-db_edit }?{ lv_action }| + iv_txt = 'Edit' ) ##NO_TEXT. ro_html->add( '
    ' ). ro_html->add( '
    ' ). - - ro_html->add( || && - |
    Type:{ ms_key-type }
    | ). - ro_html->add( || && - |
    Key:{ ms_key-value }
    | ). - - ro_html->add( '
    ' ). - ro_html->add_a( iv_txt = 'Edit' iv_act = |{ gc_action-db_edit }?{ lv_action }| ). + ro_html->add( render_record_banner( ms_key ) ). + ro_html->add( '' ). + ro_html->add( lo_toolbar->render( iv_right = abap_true ) ). ro_html->add( '
    ' ). ro_html->add( |
    { lv_data }
    | ). @@ -111,32 +122,26 @@ CLASS lcl_gui_page_db_edit IMPLEMENTATION. CREATE OBJECT ro_html. CREATE OBJECT lo_toolbar. - - ro_html->add( '
    ' ). - - " Banners - ro_html->add( || && - |
    Type:{ ms_key-type }
    | ). - ro_html->add( || && - |
    Key:{ ms_key-value }
    | ). - - " Form - ro_html->add( |
    | ). - ro_html->add( || ). - ro_html->add( || ). - ro_html->add( || ). - ro_html->add( '
    ' ). - - " Menu lo_toolbar->add( iv_act = 'submitFormById(''db_form'');' iv_txt = 'Save' iv_typ = gc_action_type-onclick iv_opt = gc_html_opt-strong ) ##NO_TEXT. - ro_html->add( '
    ' ). - ro_html->add( lo_toolbar->render( ) ). - ro_html->add( '
    ' ). + ro_html->add( '
    ' ). + + " Banners & Toolbar + ro_html->add( '
    ' ). + ro_html->add( lcl_gui_page_db_display=>render_record_banner( ms_key ) ). + ro_html->add( '' ). + ro_html->add( lo_toolbar->render( iv_right = abap_true ) ). + ro_html->add( '
    ' ). + + " Form + ro_html->add( |
    | ). + ro_html->add( || ). + ro_html->add( || ). + ro_html->add( || ). + ro_html->add( '
    ' ). ro_html->add( '
    ' ). "db_entry diff --git a/src/zabapgit_page_main.prog.abap b/src/zabapgit_page_main.prog.abap index 3b0628436..73c9720ed 100644 --- a/src/zabapgit_page_main.prog.abap +++ b/src/zabapgit_page_main.prog.abap @@ -209,7 +209,7 @@ CLASS lcl_gui_page_main IMPLEMENTATION. METHOD render_toc. DATA: lo_pback TYPE REF TO lcl_persistence_background, - lv_cur TYPE abap_bool, + lv_current TYPE abap_bool, lv_key TYPE lcl_persistence_repo=>ty_repo-key, lv_icon TYPE string, lo_repo LIKE LINE OF it_repo_list, @@ -227,10 +227,10 @@ CLASS lcl_gui_page_main IMPLEMENTATION. lt_favorites = lcl_app=>user( )->get_favorites( ). LOOP AT it_repo_list INTO lo_repo. - lv_key = lo_repo->get_key( ). - lv_cur = abap_false. + lv_key = lo_repo->get_key( ). + lv_current = abap_false. IF lv_key = mv_show. - lv_cur = abap_true. + lv_current = abap_true. ENDIF. lv_repo_title = lo_repo->get_name( ). @@ -245,7 +245,7 @@ CLASS lcl_gui_page_main IMPLEMENTATION. DELETE lt_favorites INDEX sy-tabix. " for later cleanup lo_favbar->add( iv_txt = lv_repo_title iv_act = |{ c_actions-show }?{ lv_key }| - iv_cur = lv_cur ). + iv_cur = lv_current ). ENDIF. IF lo_repo->is_offline( ) = abap_true. @@ -257,7 +257,7 @@ CLASS lcl_gui_page_main IMPLEMENTATION. lo_allbar->add( iv_txt = lv_repo_title iv_act = |{ c_actions-show }?{ lv_key }| iv_ico = lv_icon - iv_cur = lv_cur ). + iv_cur = lv_current ). ENDLOOP. " Cleanup orphan favorites (for removed repos) @@ -289,7 +289,7 @@ CLASS lcl_gui_page_main IMPLEMENTATION. ro_html->add( '' ). ro_html->add( lo_allbar->render_as_droplist( - iv_label = lcl_html=>icon( iv_name = 'three-bars/blue' iv_class = 'pad4px' ) + iv_label = lcl_html=>icon( iv_name = 'three-bars/blue' ) iv_right = abap_true iv_sort = abap_true ) ). ro_html->add( '' ). diff --git a/src/zabapgit_view_repo.prog.abap b/src/zabapgit_view_repo.prog.abap index 582507829..bdabc14fd 100644 --- a/src/zabapgit_view_repo.prog.abap +++ b/src/zabapgit_view_repo.prog.abap @@ -240,7 +240,10 @@ CLASS lcl_gui_view_repo_content IMPLEMENTATION. lo_tab_menu->add( iv_txt = 'With folders' iv_act = c_actions-toggle_folders ). ENDIF. - ro_html = lo_tab_menu->render_as_droplist( iv_label = 'SET' iv_as_angle = abap_true ). + ro_html = lo_tab_menu->render_as_droplist( + iv_label = lcl_html=>icon( iv_name = 'settings/grey' ) + iv_right = abap_true + iv_corner = abap_true ). ENDMETHOD. "render_grid_menu From 08b167cdd3ab687aa0f4012085aba71a5649da83 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Wed, 8 Mar 2017 19:43:20 +0200 Subject: [PATCH 21/28] page_diff UX filter part2 --- src/zabapgit_css_common.w3mi.data.css | 18 +++- src/zabapgit_html.prog.abap | 57 ++++++++++-- src/zabapgit_js_common.w3mi.data.js | 114 ++++++++++++++--------- src/zabapgit_page_diff.prog.abap | 70 ++++++++++----- src/zabapgit_view_repo.prog.abap | 124 +++++++++++++------------- 5 files changed, 244 insertions(+), 139 deletions(-) diff --git a/src/zabapgit_css_common.w3mi.data.css b/src/zabapgit_css_common.w3mi.data.css index 4213deeff..a4ed39579 100644 --- a/src/zabapgit_css_common.w3mi.data.css +++ b/src/zabapgit_css_common.w3mi.data.css @@ -35,6 +35,8 @@ input:focus, textarea:focus { /* COLOR PALETTE */ .grey { color: lightgrey !important; } +.grey70 { color: #b3b3b3 !important; } +.bgorange { background-color: orange; } .darkgrey { color: #808080 !important; } .attention { color: red !important; } .error { color: #d41919 !important; } @@ -698,7 +700,7 @@ div.tutorial h2 { + bite a bit of left padding for nicer look + forbids item text wrapping (maybe can be done differently) */ .nav-container ul ul li a .octicon { - padding-right: 12px; + padding-right: 10px; margin-left: -3px; } .nav-container ul.with-icons li { @@ -713,3 +715,17 @@ div.tutorial h2 { right: 0px; } .nav-container.corner > ul > li:hover > a { background-color: inherit; } + +/* Toolbar separator style */ +.nav-container ul ul li.separator +{ + font-size: x-small; + text-align: center; + padding: 4px 0; + text-transform: uppercase; + color: #bbb; + border-bottom: 1px solid #eee; + border-top: 1px solid #eee; +} +.nav-container ul ul li.separator:first-child { border-top: none; } +.nav-container ul ul li.separator:hover { background-color: inherit; } diff --git a/src/zabapgit_html.prog.abap b/src/zabapgit_html.prog.abap index 10d2cf1d4..fd7edf994 100644 --- a/src/zabapgit_html.prog.abap +++ b/src/zabapgit_html.prog.abap @@ -376,6 +376,9 @@ CLASS lcl_html_toolbar DEFINITION FINAL. PUBLIC SECTION. METHODS: + constructor + IMPORTING + iv_id TYPE string OPTIONAL, add IMPORTING iv_txt TYPE string @@ -384,7 +387,9 @@ CLASS lcl_html_toolbar DEFINITION FINAL. iv_act TYPE string OPTIONAL iv_ico TYPE string OPTIONAL iv_cur TYPE abap_bool OPTIONAL - iv_opt TYPE c OPTIONAL, + iv_opt TYPE c OPTIONAL + iv_chk TYPE abap_bool DEFAULT abap_undefined + iv_aux TYPE string OPTIONAL, count RETURNING VALUE(rv_count) TYPE i, render @@ -412,13 +417,16 @@ CLASS lcl_html_toolbar DEFINITION FINAL. opt TYPE char1, typ TYPE char1, cur TYPE abap_bool, + chk TYPE abap_bool, + aux TYPE string, END OF ty_item. TYPES tt_items TYPE STANDARD TABLE OF ty_item. - DATA mt_items TYPE tt_items. + DATA: mt_items TYPE tt_items, + mv_id TYPE string. - METHODS + METHODS: render_items IMPORTING iv_sort TYPE abap_bool OPTIONAL @@ -432,6 +440,10 @@ ENDCLASS. "lcl_html_toolbar DEFINITION *----------------------------------------------------------------------* CLASS lcl_html_toolbar IMPLEMENTATION. + METHOD constructor. + mv_id = iv_id. + ENDMETHOD. "constructor + METHOD count. rv_count = lines( mt_items ). ENDMETHOD. @@ -445,6 +457,8 @@ CLASS lcl_html_toolbar IMPLEMENTATION. OR iv_act IS INITIAL AND io_sub IS NOT INITIAL OR iv_act IS NOT INITIAL AND io_sub IS INITIAL. " Only one supplied + ASSERT NOT ( iv_chk <> abap_undefined AND io_sub IS NOT INITIAL ). + ls_item-txt = iv_txt. ls_item-act = iv_act. ls_item-ico = iv_ico. @@ -452,6 +466,9 @@ CLASS lcl_html_toolbar IMPLEMENTATION. ls_item-opt = iv_opt. ls_item-typ = iv_typ. ls_item-cur = iv_cur. + ls_item-chk = iv_chk. + ls_item-aux = iv_aux. + APPEND ls_item TO mt_items. ENDMETHOD. "add @@ -503,6 +520,9 @@ CLASS lcl_html_toolbar IMPLEMENTATION. DATA: lv_class TYPE string, lv_icon TYPE string, + lv_id TYPE string, + lv_check TYPE string, + lv_aux TYPE string, lv_has_icons TYPE abap_bool. FIELD-SYMBOLS LIKE LINE OF mt_items. @@ -513,28 +533,49 @@ CLASS lcl_html_toolbar IMPLEMENTATION. SORT mt_items BY txt ASCENDING AS TEXT. ENDIF. - " Check has icons - LOOP AT mt_items ASSIGNING WHERE ico IS NOT INITIAL. + " Check has icons or check boxes + LOOP AT mt_items ASSIGNING WHERE ico IS NOT INITIAL OR chk <> abap_undefined. lv_has_icons = abap_true. lv_class = ' class="with-icons"'. EXIT. ENDLOOP. - ro_html->add( || ). + IF mv_id IS NOT INITIAL. + lv_id = | id="{ mv_id }"|. + ENDIF. + + ro_html->add( || ). " Render items LOOP AT mt_items ASSIGNING . CLEAR: lv_class, lv_icon. + IF -typ = gc_action_type-separator. + ro_html->add( |
  • { -txt }
  • | ). + CONTINUE. + ENDIF. + IF lv_has_icons = abap_true. - lv_icon = lcl_html=>icon( -ico ). + IF -chk = abap_true. + lv_icon = lcl_html=>icon( 'check/blue' ). + lv_check = ' data-check="X"'. + ELSEIF -chk = abap_false. + lv_icon = lcl_html=>icon( 'check/grey' ). + lv_check = ' data-check=""'. + ELSE. " abap_undefined -> not a check box + lv_icon = lcl_html=>icon( -ico ). + ENDIF. ENDIF. IF -cur = abap_true. lv_class = ' class="current-menu-item"'. ENDIF. - ro_html->add( || ). + IF -aux IS NOT INITIAL. + lv_aux = | data-aux="{ -aux }"|. + ENDIF. + + ro_html->add( || ). IF -sub IS INITIAL. ro_html->add_a( iv_txt = lv_icon && -txt iv_typ = -typ diff --git a/src/zabapgit_js_common.w3mi.data.js b/src/zabapgit_js_common.w3mi.data.js index 9bc8dbbe2..1a7150e62 100644 --- a/src/zabapgit_js_common.w3mi.data.js +++ b/src/zabapgit_js_common.w3mi.data.js @@ -368,55 +368,81 @@ StageHelper.prototype.iterateStageTab = function (changeMode, cb /*, ...*/) { * Diff page logic **********************************************************/ -function diffProcessFilterClick(e) { - var target = event.target || event.srcElement; - - if (!target) return; - if (target.tagName !== "A") return; - if (target.parentNode.tagName !== "TD") return; - - var iconTd = target.parentNode.parentNode.children[0]; - - if (!iconTd) return; - if (iconTd.tagName !== "TD") return; - - var icon = iconTd.firstChild; - if (icon.tagName !== "I") return; - if (!icon.classList.contains("octicon")) return; - - var state; - if (icon.classList.contains("blue")) { - icon.classList.remove("blue"); - icon.classList.add("grey"); - state = false; - } else { - icon.classList.add("blue"); - icon.classList.remove("grey"); - state = true; - } - - return { filter: target.innerText, state: state }; +function CheckListWrapper(id, cbAction) { + this.id = document.getElementById(id); + this.cbAction = cbAction; + this.id.onclick = this.onClick.bind(this); } -function diffApplyFilter(param, action) { - var diffList = document.getElementById("diff-list"); - // console.log("Action:", param, action.filter, action.state); +CheckListWrapper.prototype.onClick = function(e) { + // Get nodes + var target = event.target || event.srcElement; + if (!target) return; + if (target.tagName !== "A") { target = target.parentNode; } // icon clicked + if (target.tagName !== "A") return; + if (target.parentNode.tagName !== "LI") return; + + var nodeA = target; + var nodeLi = target.parentNode; + var nodeIcon = target.children[0]; + if (!nodeIcon.classList.contains("octicon")) return; + + // Node updates + var option = nodeA.innerText; + var oldState = nodeLi.getAttribute("data-check"); + if (oldState === null) return; // no data-check attribute - non-checkbox + var newState = oldState === "X" ? false : true; + + if (newState) { + nodeIcon.classList.remove("grey"); + nodeIcon.classList.add("blue"); + nodeLi.setAttribute("data-check", "X"); + } else { + nodeIcon.classList.remove("blue"); + nodeIcon.classList.add("grey"); + nodeLi.setAttribute("data-check", ""); + } + + // Action callback + this.cbAction(nodeLi.getAttribute("data-aux"), option, newState); +} + +function DiffHelper(params) { + this.pageSeed = params.seed; + this.counter = 0; + + // DOM nodes + this.dom = { + diffList: document.getElementById(params.ids.diffList), + filterButton: document.getElementById(params.ids.filterMenu).parentNode + }; + + // Checklist wrapper + this.checkList = new CheckListWrapper(params.ids.filterMenu, this.onFilter.bind(this)); +} + +DiffHelper.prototype.onFilter = function(attr, target, state) { + this.applyFilter(attr, target, state); + this.highlightButton(state); +}; + +DiffHelper.prototype.applyFilter = function (attr, target, state) { + var diffList = this.dom.diffList; for (var i = diffList.children.length - 1; i >= 0; i--) { var div = diffList.children[i]; - if (div.className !== "diff") return; // Unexpected error ! - var attr = div.getAttribute("data-"+param); - if (attr === action.filter) { - div.style.display = action.state ? "" : "none"; + if (div.className !== "diff") continue; + if (div.getAttribute("data-"+attr) === target) { + div.style.display = state ? "" : "none"; } } } -function diffFilterType(e) { - var action = diffProcessFilterClick(e); - diffApplyFilter("type", action); -} - -function diffFilterUser(e) { - var action = diffProcessFilterClick(e); - diffApplyFilter("changed-by", action); -} +DiffHelper.prototype.highlightButton = function(state) { + this.counter += state ? -1 : 1; + console.log(this.counter, this.dom.filterButton); + if (this.counter > 0) { + this.dom.filterButton.classList.add("bgorange"); + } else { + this.dom.filterButton.classList.remove("bgorange"); + } +}; diff --git a/src/zabapgit_page_diff.prog.abap b/src/zabapgit_page_diff.prog.abap index 51b3d61df..4b68ade3b 100644 --- a/src/zabapgit_page_diff.prog.abap +++ b/src/zabapgit_page_diff.prog.abap @@ -33,7 +33,9 @@ CLASS lcl_gui_page_diff DEFINITION FINAL INHERITING FROM lcl_gui_page. lif_gui_page~on_event REDEFINITION. PROTECTED SECTION. - METHODS render_content REDEFINITION. + METHODS: + render_content REDEFINITION, + scripts REDEFINITION. PRIVATE SECTION. CONSTANTS: BEGIN OF c_actions, @@ -42,7 +44,8 @@ CLASS lcl_gui_page_diff DEFINITION FINAL INHERITING FROM lcl_gui_page. DATA: mt_diff_files TYPE tt_file_diff, mt_delayed_lines TYPE lcl_diff=>ty_diffs_tt, - mv_unified TYPE abap_bool VALUE abap_true. + mv_unified TYPE abap_bool VALUE abap_true, + mv_ts TYPE timestamp. METHODS render_diff IMPORTING is_diff TYPE ty_file_diff @@ -91,6 +94,8 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. ms_control-page_title = 'DIFF'. mv_unified = lcl_app=>user( )->get_diff_unified( ). + GET TIME STAMP FIELD mv_ts. + ASSERT is_file IS INITIAL OR is_object IS INITIAL. " just one passed lo_repo ?= lcl_app=>repo_srv( )->get( iv_key ). @@ -197,6 +202,7 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. -type = 'other'. ENDIF. + " Diff data IF -fstate = c_fstate-remote. " Remote file leading changes CREATE OBJECT -o_diff EXPORTING @@ -220,6 +226,7 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. FIELD-SYMBOLS: LIKE LINE OF mt_diff_files, TYPE string. + " Get unique LOOP AT mt_diff_files ASSIGNING . APPEND -type TO lt_types. APPEND -changed_by TO lt_users. @@ -230,27 +237,32 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. CREATE OBJECT ro_menu. - IF lines( lt_types ) > 1. - CREATE OBJECT lo_sub. - LOOP AT lt_types ASSIGNING . - lo_sub->add( iv_txt = - iv_typ = gc_action_type-onclick - iv_ico = 'check/blue' - iv_act = 'diffFilterType(event);' ). - ENDLOOP. - ro_menu->add( iv_txt = 'Filter type' - io_sub = lo_sub ) ##NO_TEXT. - ENDIF. + IF lines( lt_types ) + lines( lt_users ) > 1. + CREATE OBJECT lo_sub EXPORTING iv_id = 'diff-filter'. - IF lines( lt_users ) > 1. - CREATE OBJECT lo_sub. - LOOP AT lt_users ASSIGNING . - lo_sub->add( iv_txt = - iv_typ = gc_action_type-onclick - iv_ico = 'check/blue' - iv_act = 'diffFilterUser(event);' ). - ENDLOOP. - ro_menu->add( iv_txt = 'Filter user' + " File types + IF lines( lt_types ) > 1. + lo_sub->add( iv_txt = 'TYPE' iv_typ = gc_action_type-separator ). + LOOP AT lt_types ASSIGNING . + lo_sub->add( iv_txt = + iv_typ = gc_action_type-onclick + iv_aux = 'type' + iv_chk = abap_true ). + ENDLOOP. + ENDIF. + + " Changed by + IF lines( lt_users ) > 1. + lo_sub->add( iv_txt = 'CHANGED BY' iv_typ = gc_action_type-separator ). + LOOP AT lt_users ASSIGNING . + lo_sub->add( iv_txt = + iv_typ = gc_action_type-onclick + iv_aux = 'changed-by' + iv_chk = abap_true ). + ENDLOOP. + ENDIF. + + ro_menu->add( iv_txt = 'Filter' io_sub = lo_sub ) ##NO_TEXT. ENDIF. @@ -284,6 +296,7 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. CREATE OBJECT ro_html. ro_html->add( '
    ' ). + ro_html->add( lcl_gui_chunk_lib=>render_js_error_banner( ) ). LOOP AT mt_diff_files INTO ls_diff_file. lcl_progress=>show( iv_key = 'Diff' iv_current = sy-tabix @@ -553,4 +566,17 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. ENDMETHOD. "render_line_unified + METHOD scripts. + + CREATE OBJECT ro_html. + + ro_html->add( 'var gHelper = new DiffHelper({' ). + ro_html->add( | seed: "diff{ mv_ts }",| ). + ro_html->add( ' ids: {' ). + ro_html->add( ' diffList: "diff-list",' ). + ro_html->add( ' filterMenu: "diff-filter" ' ). + ro_html->add( ' }' ). + ro_html->add( '});' ). + + ENDMETHOD. "scripts ENDCLASS. "lcl_gui_page_diff diff --git a/src/zabapgit_view_repo.prog.abap b/src/zabapgit_view_repo.prog.abap index bdabc14fd..f61e2dea4 100644 --- a/src/zabapgit_view_repo.prog.abap +++ b/src/zabapgit_view_repo.prog.abap @@ -30,13 +30,18 @@ CLASS lcl_gui_view_repo_content DEFINITION FINAL. mv_changes_only TYPE abap_bool. METHODS: - render_head_menu + render_head_line IMPORTING iv_lstate TYPE char1 iv_rstate TYPE char1 RETURNING VALUE(ro_html) TYPE REF TO lcl_html RAISING lcx_exception, - render_grid_menu - RETURNING VALUE(ro_html) TYPE REF TO lcl_html + build_head_menu + IMPORTING iv_lstate TYPE char1 + iv_rstate TYPE char1 + RETURNING VALUE(ro_toolbar) TYPE REF TO lcl_html_toolbar + RAISING lcx_exception, + build_grid_menu + RETURNING VALUE(ro_toolbar) TYPE REF TO lcl_html_toolbar RAISING lcx_exception, render_item IMPORTING is_item TYPE lcl_repo_content_browser=>ty_repo_item @@ -150,7 +155,7 @@ CLASS lcl_gui_view_repo_content IMPLEMENTATION. _reduce_state lv_rstate -rstate. ENDLOOP. - ro_html->add( render_head_menu( iv_lstate = lv_lstate + ro_html->add( render_head_line( iv_lstate = lv_lstate iv_rstate = lv_rstate ) ). lo_log = lo_browser->get_log( ). @@ -161,7 +166,6 @@ CLASS lcl_gui_view_repo_content IMPLEMENTATION. ENDIF. ro_html->add( '
    ' ). - ro_html->add( render_grid_menu( ) ). " Repo content table ro_html->add( '' ). @@ -203,62 +207,67 @@ CLASS lcl_gui_view_repo_content IMPLEMENTATION. ro_html->add( '' ). CATCH lcx_exception INTO lx_error. - ro_html->add( render_head_menu( iv_lstate = lv_lstate iv_rstate = lv_rstate ) ). + ro_html->add( render_head_line( iv_lstate = lv_lstate iv_rstate = lv_rstate ) ). ro_html->add( lcl_gui_chunk_lib=>render_error( ix_error = lx_error ) ). ENDTRY. ENDMETHOD. "lif_gui_page~render - METHOD render_grid_menu. + METHOD render_head_line. - DATA lo_tab_menu TYPE REF TO lcl_html_toolbar. + DATA lo_toolbar TYPE REF TO lcl_html_toolbar. - CREATE OBJECT lo_tab_menu. + CREATE OBJECT ro_html. + lo_toolbar = build_head_menu( iv_lstate = iv_lstate iv_rstate = iv_rstate ). + + ro_html->add( '
    ' ). + ro_html->add( '
    ' ). + + IF mv_show_folders = abap_true. + ro_html->add( || ). + ENDIF. + + ro_html->add( '' ). + ro_html->add( '
    { mv_cur_dir }' ). + ro_html->add( lo_toolbar->render( iv_right = abap_true ) ). + ro_html->add( '
    ' ). + ro_html->add( '
    ' ). + + ENDMETHOD. "render_head_line + + METHOD build_grid_menu. + + CREATE OBJECT ro_toolbar. IF mo_repo->is_offline( ) = abap_false. + ro_toolbar->add( " Show/Hide files + iv_txt = 'Show files' + iv_chk = boolc( NOT mv_hide_files = abap_true ) + iv_act = c_actions-toggle_hide_files ). - " Show/Hide files - IF mv_hide_files = abap_true. - lo_tab_menu->add( iv_txt = 'Show files' iv_act = c_actions-toggle_hide_files ). - ELSE. - lo_tab_menu->add( iv_txt = 'Hide files' iv_act = c_actions-toggle_hide_files ). - ENDIF. - - " Show changes only - IF mv_changes_only = abap_true. - lo_tab_menu->add( iv_txt = 'All objects' iv_act = c_actions-toggle_changes ). - ELSE. - lo_tab_menu->add( iv_txt = 'Changed only' iv_act = c_actions-toggle_changes ). - ENDIF. - + ro_toolbar->add( " Show changes only + iv_txt = 'Show changes only' + iv_chk = mv_changes_only + iv_act = c_actions-toggle_changes ). ENDIF. - " Show/Hide folders - IF mv_show_folders = abap_true. - lo_tab_menu->add( iv_txt = 'Plain list' iv_act = c_actions-toggle_folders ). - ELSE. - lo_tab_menu->add( iv_txt = 'With folders' iv_act = c_actions-toggle_folders ). - ENDIF. + ro_toolbar->add( " Show/Hide folders + iv_txt = 'Show folders' + iv_chk = mv_show_folders + iv_act = c_actions-toggle_folders ). - ro_html = lo_tab_menu->render_as_droplist( - iv_label = lcl_html=>icon( iv_name = 'settings/grey' ) - iv_right = abap_true - iv_corner = abap_true ). + ENDMETHOD. "build_grid_menu - ENDMETHOD. "render_grid_menu + METHOD build_head_menu. - METHOD render_head_menu. - - DATA: lo_toolbar TYPE REF TO lcl_html_toolbar, - lo_tb_advanced TYPE REF TO lcl_html_toolbar, + DATA: lo_tb_advanced TYPE REF TO lcl_html_toolbar, lo_tb_branch TYPE REF TO lcl_html_toolbar, lv_key TYPE lcl_persistence_db=>ty_value, lv_wp_opt LIKE gc_html_opt-crossout, lv_pull_opt LIKE gc_html_opt-crossout, lo_repo_online TYPE REF TO lcl_repo_online. - CREATE OBJECT ro_html. - CREATE OBJECT lo_toolbar. + CREATE OBJECT ro_toolbar. CREATE OBJECT lo_tb_branch. CREATE OBJECT lo_tb_advanced. @@ -316,17 +325,17 @@ CLASS lcl_gui_view_repo_content IMPLEMENTATION. IF mo_repo->is_offline( ) = abap_false. " Online ? TRY. IF iv_rstate IS NOT INITIAL. " Something new at remote - lo_toolbar->add( iv_txt = 'Pull' + ro_toolbar->add( iv_txt = 'Pull' iv_act = |{ gc_action-git_pull }?{ lv_key }| iv_opt = lv_pull_opt ). ENDIF. IF iv_lstate IS NOT INITIAL. " Something new at local - lo_toolbar->add( iv_txt = 'Stage' + ro_toolbar->add( iv_txt = 'Stage' iv_act = |{ gc_action-go_stage }?{ lv_key }| iv_opt = gc_html_opt-strong ). ENDIF. IF iv_rstate IS NOT INITIAL OR iv_lstate IS NOT INITIAL. " Any changes - lo_toolbar->add( iv_txt = 'Show diff' + ro_toolbar->add( iv_txt = 'Show diff' iv_act = |{ gc_action-go_diff }?key={ lv_key }| iv_opt = gc_html_opt-strong ). ENDIF. @@ -334,38 +343,25 @@ CLASS lcl_gui_view_repo_content IMPLEMENTATION. " authorization error or repository does not exist " ignore error ENDTRY. - lo_toolbar->add( iv_txt = 'Branch' + ro_toolbar->add( iv_txt = 'Branch' io_sub = lo_tb_branch ) ##NO_TEXT. ELSE. - lo_toolbar->add( iv_txt = 'Import ZIP' + ro_toolbar->add( iv_txt = 'Import ZIP' iv_act = |{ gc_action-zip_import }?{ lv_key }| iv_opt = gc_html_opt-strong ). - lo_toolbar->add( iv_txt = 'Export ZIP' + ro_toolbar->add( iv_txt = 'Export ZIP' iv_act = |{ gc_action-zip_export }?{ lv_key }| iv_opt = gc_html_opt-strong ). ENDIF. - lo_toolbar->add( iv_txt = 'Advanced' + ro_toolbar->add( iv_txt = 'Advanced' io_sub = lo_tb_advanced ) ##NO_TEXT. - lo_toolbar->add( iv_txt = 'Refresh' + ro_toolbar->add( iv_txt = 'Refresh' iv_act = |{ gc_action-repo_refresh }?{ lv_key }| ). + ro_toolbar->add( iv_txt = lcl_html=>icon( iv_name = 'settings/grey70' ) + io_sub = build_grid_menu( ) ). - " Render ========================================== - ro_html->add( '
    ' ). - ro_html->add( '' ). - - IF mv_show_folders = abap_true. - ro_html->add( || ). - ENDIF. - - ro_html->add( '' ). - ro_html->add( '
    { mv_cur_dir }' ). - ro_html->add( lo_toolbar->render( iv_right = abap_true ) ). - ro_html->add( '
    ' ). - ro_html->add( '
    ' ). - - - ENDMETHOD. "render_head_menu + ENDMETHOD. "build_head_menu METHOD get_item_class. From 59f236113559aaec220a0df1b89fc5e9fb786d88 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Wed, 8 Mar 2017 21:45:03 +0200 Subject: [PATCH 22/28] css clearfix --- src/zabapgit_css_common.w3mi.data.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/zabapgit_css_common.w3mi.data.css b/src/zabapgit_css_common.w3mi.data.css index a4ed39579..e1185389d 100644 --- a/src/zabapgit_css_common.w3mi.data.css +++ b/src/zabapgit_css_common.w3mi.data.css @@ -302,7 +302,6 @@ input.stage-filter { width: 18em; } /* COMMIT */ div.form-container { - margin: 0.5em 0em; background-color: #F8F8F8; padding: 1em 1em; } @@ -627,6 +626,9 @@ div.tutorial h2 { padding: 0 12px; } +/* clearfix https://css-tricks.com/snippets/css/clear-fix/ */ +.nav-container:after { clear: both; display: block; content: ""; } + /* submenues align to left or right border of the active item depending on .float-right modifier */ .nav-container ul li From be79b3234a34b9fc76acb40109fe2eb97e465c47 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Fri, 10 Mar 2017 16:26:25 +0200 Subject: [PATCH 23/28] page_diff UX filter finalizing --- src/zabapgit_css_common.w3mi.data.css | 1 + src/zabapgit_gui_router.prog.abap | 64 +++++---- src/zabapgit_html.prog.abap | 7 +- src/zabapgit_html_action_utils.prog.abap | 45 +++++-- src/zabapgit_js_common.w3mi.data.js | 79 +++++++++-- src/zabapgit_page_diff.prog.abap | 159 +++++++++++++++++------ src/zabapgit_page_stage.prog.abap | 43 +++--- src/zabapgit_stage.prog.abap | 4 +- 8 files changed, 294 insertions(+), 108 deletions(-) diff --git a/src/zabapgit_css_common.w3mi.data.css b/src/zabapgit_css_common.w3mi.data.css index e1185389d..9068ba7ab 100644 --- a/src/zabapgit_css_common.w3mi.data.css +++ b/src/zabapgit_css_common.w3mi.data.css @@ -48,6 +48,7 @@ input:focus, textarea:focus { .emphasis { font-weight: bold !important; } .crossout { text-decoration: line-through !important; } .right { text-align:right; } +.center { text-align:center; } .paddings { padding: 0.5em 0.5em; } .pad-sides { padding-left: 0.3em; padding-right: 0.3em; } .margin-v5 { margin-top: 0.5em; margin-bottom: 0.5em; } diff --git a/src/zabapgit_gui_router.prog.abap b/src/zabapgit_gui_router.prog.abap index d910693cb..222cf4b2d 100644 --- a/src/zabapgit_gui_router.prog.abap +++ b/src/zabapgit_gui_router.prog.abap @@ -26,6 +26,7 @@ CLASS lcl_gui_router DEFINITION FINAL. METHODS get_page_diff IMPORTING iv_getdata TYPE clike + iv_prev_page TYPE clike RETURNING VALUE(ri_page) TYPE REF TO lif_gui_page RAISING lcx_exception. @@ -35,8 +36,8 @@ CLASS lcl_gui_router DEFINITION FINAL. RAISING lcx_exception. METHODS get_page_stage - IMPORTING iv_key TYPE lcl_persistence_repo=>ty_repo-key - RETURNING VALUE(ri_page) TYPE REF TO lif_gui_page + IMPORTING iv_getdata TYPE clike + RETURNING VALUE(ri_page) TYPE REF TO lif_gui_page RAISING lcx_exception. METHODS get_page_db_by_name @@ -72,7 +73,7 @@ CLASS lcl_gui_router IMPLEMENTATION. lv_url = iv_getdata. " TODO refactor CASE iv_action. - " General routing + " General PAGE routing WHEN gc_action-go_main " Go Main page OR gc_action-go_explore " Go Explore page OR gc_action-go_db " Go DB util page @@ -85,11 +86,17 @@ CLASS lcl_gui_router IMPLEMENTATION. ei_page = get_page_background( lv_key ). ev_state = gc_event_state-new_page. WHEN gc_action-go_diff. " Go Diff page - ei_page = get_page_diff( iv_getdata ). - ev_state = gc_event_state-new_page. - WHEN gc_action-go_stage. " Go Staging page - ei_page = get_page_stage( lv_key ). + ei_page = get_page_diff( + iv_getdata = iv_getdata + iv_prev_page = iv_prev_page ). ev_state = gc_event_state-new_page_w_bookmark. + WHEN gc_action-go_stage. " Go Staging page + ei_page = get_page_stage( iv_getdata ). + IF iv_prev_page = 'PAGE_DIFF'. + ev_state = gc_event_state-new_page. + ELSE. + ev_state = gc_event_state-new_page_w_bookmark. + ENDIF. WHEN gc_action-go_branch_overview. " Go repo branch overview ei_page = get_page_branch_overview( iv_getdata ). ev_state = gc_event_state-new_page. @@ -102,12 +109,12 @@ CLASS lcl_gui_router IMPLEMENTATION. " SAP GUI actions WHEN gc_action-jump. " Open object editor - lcl_html_action_utils=>jump_decode( EXPORTING iv_string = iv_getdata - IMPORTING ev_obj_type = ls_item-obj_type - ev_obj_name = ls_item-obj_name ). + lcl_html_action_utils=>jump_decode( + EXPORTING iv_string = iv_getdata + IMPORTING ev_obj_type = ls_item-obj_type + ev_obj_name = ls_item-obj_name ). lcl_objects=>jump( ls_item ). ev_state = gc_event_state-no_more_act. - WHEN gc_action-jump_pkg. " Open SE80 lcl_services_repo=>open_se80( |{ iv_getdata }| ). ev_state = gc_event_state-no_more_act. @@ -128,7 +135,7 @@ CLASS lcl_gui_router IMPLEMENTATION. lcl_services_db=>update( ls_db ). ev_state = gc_event_state-go_back. - " Abapgit services actions + " ABAPGIT services actions WHEN gc_action-abapgit_home. " Go abapGit homepage lcl_services_abapgit=>open_abapgit_homepage( ). ev_state = gc_event_state-no_more_act. @@ -142,7 +149,7 @@ CLASS lcl_gui_router IMPLEMENTATION. lcl_services_abapgit=>install_abapgit_pi( ). ev_state = gc_event_state-re_render. - " Repository services actions + " REPOSITORY services actions WHEN gc_action-repo_newoffline. " New offline repo lcl_services_repo=>new_offline( ). ev_state = gc_event_state-re_render. @@ -182,7 +189,7 @@ CLASS lcl_gui_router IMPLEMENTATION. lcl_zip=>export_object( ). ev_state = gc_event_state-no_more_act. - " Remote origin manipulations + " Remote ORIGIN manipulations WHEN gc_action-repo_remote_attach. " Remote attach lcl_services_repo=>remote_attach( lv_key ). ev_state = gc_event_state-re_render. @@ -193,7 +200,7 @@ CLASS lcl_gui_router IMPLEMENTATION. lcl_services_repo=>remote_change( lv_key ). ev_state = gc_event_state-re_render. - " Git actions + " GIT actions WHEN gc_action-git_pull. " GIT Pull lcl_services_git=>pull( lv_key ). ev_state = gc_event_state-re_render. @@ -203,10 +210,10 @@ CLASS lcl_gui_router IMPLEMENTATION. WHEN gc_action-git_branch_create. " GIT Create new branch lcl_services_git=>create_branch( lv_key ). ev_state = gc_event_state-re_render. - WHEN gc_action-git_branch_delete. " Delete remote branch + WHEN gc_action-git_branch_delete. " GIT Delete remote branch lcl_services_git=>delete_branch( lv_key ). ev_state = gc_event_state-re_render. - WHEN gc_action-git_branch_switch. " Switch branch + WHEN gc_action-git_branch_switch. " GIT Switch branch lcl_services_git=>switch_branch( lv_key ). ev_state = gc_event_state-re_render. @@ -289,9 +296,10 @@ CLASS lcl_gui_router IMPLEMENTATION. CREATE OBJECT lo_page EXPORTING - iv_key = lv_key - is_file = ls_file - is_object = ls_object. + iv_key = lv_key + is_file = ls_file + is_object = ls_object + iv_supress_stage = boolc( iv_prev_page = 'PAGE_STAGE' ). ri_page = lo_page. @@ -300,17 +308,29 @@ CLASS lcl_gui_router IMPLEMENTATION. METHOD get_page_stage. DATA: lo_repo TYPE REF TO lcl_repo_online, + lv_key TYPE lcl_persistence_repo=>ty_repo-key, + lv_seed TYPE string, lo_stage_page TYPE REF TO lcl_gui_page_stage. + FIND FIRST OCCURRENCE OF '=' IN iv_getdata. + IF sy-subrc <> 0. " Not found ? -> just repo key in params + lv_key = iv_getdata. + ELSE. + lcl_html_action_utils=>stage_decode( + EXPORTING iv_getdata = iv_getdata + IMPORTING ev_key = lv_key + ev_seed = lv_seed ). + ENDIF. - lo_repo ?= lcl_app=>repo_srv( )->get( iv_key ). + lo_repo ?= lcl_app=>repo_srv( )->get( lv_key ). " force refresh on stage, to make sure the latest local and remote files are used lo_repo->refresh( ). CREATE OBJECT lo_stage_page EXPORTING - io_repo = lo_repo. + io_repo = lo_repo + iv_seed = lv_seed. ri_page = lo_stage_page. diff --git a/src/zabapgit_html.prog.abap b/src/zabapgit_html.prog.abap index fd7edf994..f9b984e35 100644 --- a/src/zabapgit_html.prog.abap +++ b/src/zabapgit_html.prog.abap @@ -389,7 +389,8 @@ CLASS lcl_html_toolbar DEFINITION FINAL. iv_cur TYPE abap_bool OPTIONAL iv_opt TYPE c OPTIONAL iv_chk TYPE abap_bool DEFAULT abap_undefined - iv_aux TYPE string OPTIONAL, + iv_aux TYPE string OPTIONAL + iv_id TYPE string OPTIONAL, count RETURNING VALUE(rv_count) TYPE i, render @@ -419,6 +420,7 @@ CLASS lcl_html_toolbar DEFINITION FINAL. cur TYPE abap_bool, chk TYPE abap_bool, aux TYPE string, + id TYPE string, END OF ty_item. TYPES tt_items TYPE STANDARD TABLE OF ty_item. @@ -468,6 +470,7 @@ CLASS lcl_html_toolbar IMPLEMENTATION. ls_item-cur = iv_cur. ls_item-chk = iv_chk. ls_item-aux = iv_aux. + ls_item-id = iv_id. APPEND ls_item TO mt_items. @@ -580,11 +583,13 @@ CLASS lcl_html_toolbar IMPLEMENTATION. ro_html->add_a( iv_txt = lv_icon && -txt iv_typ = -typ iv_act = -act + iv_id = -id iv_opt = -opt ). ELSE. ro_html->add_a( iv_txt = lv_icon && -txt iv_typ = gc_action_type-dummy iv_act = '' + iv_id = -id iv_opt = -opt ). ro_html->add( -sub->render_items( iv_sort = iv_sort ) ). ENDIF. diff --git a/src/zabapgit_html_action_utils.prog.abap b/src/zabapgit_html_action_utils.prog.abap index ccf844469..f560272e3 100644 --- a/src/zabapgit_html_action_utils.prog.abap +++ b/src/zabapgit_html_action_utils.prog.abap @@ -11,6 +11,10 @@ CLASS lcl_html_action_utils DEFINITION FINAL. CLASS-METHODS field_keys_to_upper CHANGING ct_fields TYPE tihttpnvp. + CLASS-METHODS parse_fields + IMPORTING iv_string TYPE clike + RETURNING VALUE(rt_fields) TYPE tihttpnvp. + CLASS-METHODS add_field IMPORTING name TYPE string iv TYPE any @@ -78,6 +82,11 @@ CLASS lcl_html_action_utils DEFINITION FINAL. IMPORTING iv_getdata TYPE clike RETURNING VALUE(rs_fields) TYPE lcl_persistence_background=>ty_background. + CLASS-METHODS stage_decode + IMPORTING iv_getdata TYPE clike + EXPORTING ev_key TYPE lcl_persistence_repo=>ty_repo-key + ev_seed TYPE string + RAISING lcx_exception. ENDCLASS. "lcl_html_action_utils DEFINITION @@ -96,6 +105,13 @@ CLASS lcl_html_action_utils IMPLEMENTATION. ENDMETHOD. "field_keys_to_upper + METHOD parse_fields. + + rt_fields = cl_http_utility=>if_http_utility~string_to_fields( |{ iv_string }| ). + field_keys_to_upper( CHANGING ct_fields = rt_fields ). + + ENDMETHOD. " parse_fields. + METHOD add_field. DATA ls_field LIKE LINE OF ct. @@ -216,8 +232,7 @@ CLASS lcl_html_action_utils IMPLEMENTATION. ASSERT eg_file IS SUPPLIED OR eg_object IS SUPPLIED. CLEAR: ev_key, eg_file, eg_object. - lt_fields = cl_http_utility=>if_http_utility~string_to_fields( |{ iv_string }| ). - field_keys_to_upper( CHANGING ct_fields = lt_fields ). + lt_fields = parse_fields( iv_string ). get_field( EXPORTING name = 'KEY' it = lt_fields CHANGING cv = ev_key ). @@ -248,8 +263,7 @@ CLASS lcl_html_action_utils IMPLEMENTATION. DATA: lt_fields TYPE tihttpnvp. - lt_fields = cl_http_utility=>if_http_utility~string_to_fields( |{ iv_string }| ). - field_keys_to_upper( CHANGING ct_fields = lt_fields ). + lt_fields = parse_fields( iv_string ). get_field( EXPORTING name = 'TYPE' it = lt_fields CHANGING cv = rs_key-type ). get_field( EXPORTING name = 'VALUE' it = lt_fields CHANGING cv = rs_key-value ). @@ -265,8 +279,7 @@ CLASS lcl_html_action_utils IMPLEMENTATION. CONCATENATE LINES OF it_postdata INTO lv_string. rs_content = dbkey_decode( lv_string ). - lt_fields = cl_http_utility=>if_http_utility~string_to_fields( lv_string ). - field_keys_to_upper( CHANGING ct_fields = lt_fields ). + lt_fields = parse_fields( lv_string ). get_field( EXPORTING name = 'XMLDATA' it = lt_fields CHANGING cv = rs_content-data_str ). IF rs_content-data_str(1) <> '<' AND rs_content-data_str+1(1) = '<'. " Hmmm ??? @@ -290,8 +303,7 @@ CLASS lcl_html_action_utils IMPLEMENTATION. CONCATENATE LINES OF it_postdata INTO lv_string. REPLACE ALL OCCURRENCES OF gc_newline IN lv_string WITH lc_replace. - lt_fields = cl_http_utility=>if_http_utility~string_to_fields( lv_string ). - field_keys_to_upper( CHANGING ct_fields = lt_fields ). + lt_fields = parse_fields( lv_string ). get_field( EXPORTING name = 'COMMITTER_NAME' it = lt_fields CHANGING cv = es_fields ). get_field( EXPORTING name = 'COMMITTER_EMAIL' it = lt_fields CHANGING cv = es_fields ). @@ -312,9 +324,7 @@ CLASS lcl_html_action_utils IMPLEMENTATION. DATA: lt_fields TYPE tihttpnvp. - - lt_fields = cl_http_utility=>if_http_utility~string_to_fields( |{ iv_getdata }| ). - field_keys_to_upper( CHANGING ct_fields = lt_fields ). + lt_fields = parse_fields( iv_getdata ). get_field( EXPORTING name = 'METHOD' it = lt_fields CHANGING cv = rs_fields ). get_field( EXPORTING name = 'USERNAME' it = lt_fields CHANGING cv = rs_fields ). @@ -327,4 +337,17 @@ CLASS lcl_html_action_utils IMPLEMENTATION. ENDMETHOD. "decode_bg_update + METHOD stage_decode. + + DATA: lt_fields TYPE tihttpnvp. + + lt_fields = parse_fields( iv_getdata ). + + get_field( EXPORTING name = 'KEY' it = lt_fields CHANGING cv = ev_key ). + get_field( EXPORTING name = 'SEED' it = lt_fields CHANGING cv = ev_seed ). + + ASSERT NOT ev_key IS INITIAL. + + ENDMETHOD. " stage_decode. + ENDCLASS. "lcl_html_action_utils IMPLEMENTATION diff --git a/src/zabapgit_js_common.w3mi.data.js b/src/zabapgit_js_common.w3mi.data.js index 1a7150e62..4e227e2c5 100644 --- a/src/zabapgit_js_common.w3mi.data.js +++ b/src/zabapgit_js_common.w3mi.data.js @@ -44,9 +44,9 @@ function debugOutput(text, dstID) { } // Create hidden form and submit with sapevent -function submitSapeventForm(params, action) { +function submitSapeventForm(params, action, method) { var form = document.createElement("form"); - form.setAttribute("method", "post"); + form.setAttribute("method", method || "post"); form.setAttribute("action", "sapevent:" + action); for(var key in params) { @@ -248,6 +248,7 @@ StageHelper.prototype.onSearch = function (e) { } } +// Apply filter to a single stage line - hide or show StageHelper.prototype.applyFilterToRow = function (row, filter) { var td = row.cells[this.col.name]; var origTxt = td.innerText; // without tags @@ -365,7 +366,7 @@ StageHelper.prototype.iterateStageTab = function (changeMode, cb /*, ...*/) { } /********************************************************** - * Diff page logic + * Check list wrapper **********************************************************/ function CheckListWrapper(id, cbAction) { @@ -407,39 +408,91 @@ CheckListWrapper.prototype.onClick = function(e) { this.cbAction(nodeLi.getAttribute("data-aux"), option, newState); } +/********************************************************** + * Diff page logic + **********************************************************/ + +// Diff helper constructor function DiffHelper(params) { - this.pageSeed = params.seed; - this.counter = 0; + this.pageSeed = params.seed; + this.counter = 0; + this.stageAction = params.stageAction; // DOM nodes this.dom = { - diffList: document.getElementById(params.ids.diffList), - filterButton: document.getElementById(params.ids.filterMenu).parentNode + diffList: document.getElementById(params.ids.diffList), + stageButton: document.getElementById(params.ids.stageButton) }; + this.repoKey = this.dom.diffList.getAttribute("data-repo-key"); + if (!this.repoKey) return; // Unexpected + // Checklist wrapper - this.checkList = new CheckListWrapper(params.ids.filterMenu, this.onFilter.bind(this)); + if (document.getElementById(params.ids.filterMenu)) { + this.checkList = new CheckListWrapper(params.ids.filterMenu, this.onFilter.bind(this)); + this.dom.filterButton = document.getElementById(params.ids.filterMenu).parentNode; + } + + // Hijack stage command + if (this.dom.stageButton) { + this.dom.stageButton.href = "#"; + this.dom.stageButton.onclick = this.onStage.bind(this); + } } +// Action on filter click DiffHelper.prototype.onFilter = function(attr, target, state) { this.applyFilter(attr, target, state); this.highlightButton(state); }; +// Hide/show diff based on params DiffHelper.prototype.applyFilter = function (attr, target, state) { - var diffList = this.dom.diffList; - for (var i = diffList.children.length - 1; i >= 0; i--) { - var div = diffList.children[i]; - if (div.className !== "diff") continue; + this.iterateDiffList(function(div) { if (div.getAttribute("data-"+attr) === target) { div.style.display = state ? "" : "none"; } + }); +} + +// Action on stage -> save visible diffs as state for stage page +DiffHelper.prototype.onStage = function (e) { + if (window.sessionStorage) { + var data = this.buildStageCache(); + window.sessionStorage.setItem(this.pageSeed, JSON.stringify(data)); + } + var getParams = {key: this.repoKey, seed: this.pageSeed}; + submitSapeventForm(getParams, this.stageAction, "get"); +} + +// Collect visible diffs +DiffHelper.prototype.buildStageCache = function () { + var list = {}; + this.iterateDiffList(function(div) { + var filename = div.getAttribute("data-file"); + if (!div.style.display && filename) { // No display override - visible !! + list[filename] = "A"; // Add + } + }); + return list; +} + +// Table iterator +DiffHelper.prototype.iterateDiffList = function (cb /*, ...*/) { + var restArgs = Array.prototype.slice.call(arguments, 1); + var diffList = this.dom.diffList; + + for (var i = 0, iN = diffList.children.length; i < iN; i++) { + var div = diffList.children[i]; + if (div.className !== "diff") continue; + args = [div].concat(restArgs); + cb.apply(this, args); // callback } } +// Highlight Filter button if filter is activate DiffHelper.prototype.highlightButton = function(state) { this.counter += state ? -1 : 1; - console.log(this.counter, this.dom.filterButton); if (this.counter > 0) { this.dom.filterButton.classList.add("bgorange"); } else { diff --git a/src/zabapgit_page_diff.prog.abap b/src/zabapgit_page_diff.prog.abap index 4b68ade3b..cef8bd75f 100644 --- a/src/zabapgit_page_diff.prog.abap +++ b/src/zabapgit_page_diff.prog.abap @@ -14,6 +14,7 @@ CLASS lcl_gui_page_diff DEFINITION FINAL INHERITING FROM lcl_gui_page. END OF c_fstate. TYPES: BEGIN OF ty_file_diff, + path TYPE string, filename TYPE string, lstate TYPE char1, rstate TYPE char1, @@ -26,9 +27,10 @@ CLASS lcl_gui_page_diff DEFINITION FINAL INHERITING FROM lcl_gui_page. METHODS: constructor - IMPORTING iv_key TYPE lcl_persistence_repo=>ty_repo-key - is_file TYPE ty_file OPTIONAL - is_object TYPE ty_item OPTIONAL + IMPORTING iv_key TYPE lcl_persistence_repo=>ty_repo-key + is_file TYPE ty_file OPTIONAL + is_object TYPE ty_item OPTIONAL + iv_supress_stage TYPE abap_bool DEFAULT abap_false RAISING lcx_exception, lif_gui_page~on_event REDEFINITION. @@ -45,7 +47,8 @@ CLASS lcl_gui_page_diff DEFINITION FINAL INHERITING FROM lcl_gui_page. DATA: mt_diff_files TYPE tt_file_diff, mt_delayed_lines TYPE lcl_diff=>ty_diffs_tt, mv_unified TYPE abap_bool VALUE abap_true, - mv_ts TYPE timestamp. + mv_repo_key TYPE lcl_persistence_repo=>ty_repo-key, + mv_seed TYPE string. METHODS render_diff IMPORTING is_diff TYPE ty_file_diff @@ -75,7 +78,12 @@ CLASS lcl_gui_page_diff DEFINITION FINAL INHERITING FROM lcl_gui_page. is_status TYPE ty_result RAISING lcx_exception. METHODS build_menu - RETURNING VALUE(ro_menu) TYPE REF TO lcl_html_toolbar. + IMPORTING iv_supress_stage TYPE abap_bool + RETURNING VALUE(ro_menu) TYPE REF TO lcl_html_toolbar. + METHODS is_binary + IMPORTING iv_d1 TYPE xstring + iv_d2 TYPE xstring + RETURNING VALUE(rv_yes) TYPE abap_bool. ENDCLASS. "lcl_gui_page_diff @@ -86,15 +94,18 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. DATA: lt_remote TYPE ty_files_tt, lt_local TYPE ty_files_item_tt, lt_status TYPE ty_results_tt, - lo_repo TYPE REF TO lcl_repo_online. + lo_repo TYPE REF TO lcl_repo_online, + lv_ts TYPE timestamp. FIELD-SYMBOLS: LIKE LINE OF lt_status. super->constructor( ). ms_control-page_title = 'DIFF'. mv_unified = lcl_app=>user( )->get_diff_unified( ). + mv_repo_key = iv_key. - GET TIME STAMP FIELD mv_ts. + GET TIME STAMP FIELD lv_ts. + mv_seed = |diff{ lv_ts }|. ASSERT is_file IS INITIAL OR is_object IS INITIAL. " just one passed @@ -137,7 +148,7 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. lcx_exception=>raise( 'PAGE_DIFF ERROR: No diff files found' ). ENDIF. - ms_control-page_menu = build_menu( ). + ms_control-page_menu = build_menu( iv_supress_stage ). ENDMETHOD. @@ -172,6 +183,7 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. ENDIF. APPEND INITIAL LINE TO mt_diff_files ASSIGNING . + -path = is_status-path. -filename = is_status-filename. -lstate = is_status-lstate. -rstate = is_status-rstate. @@ -202,21 +214,65 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. -type = 'other'. ENDIF. + IF -type = 'other' + AND is_binary( iv_d1 = -data iv_d2 = -file-data ) = abap_true. + -type = 'binary'. + ENDIF. + " Diff data - IF -fstate = c_fstate-remote. " Remote file leading changes - CREATE OBJECT -o_diff - EXPORTING - iv_new = -data - iv_old = -file-data. - ELSE. " Local leading changes or both were modified - CREATE OBJECT -o_diff - EXPORTING - iv_new = -file-data - iv_old = -data. + IF -type <> 'binary'. + IF -fstate = c_fstate-remote. " Remote file leading changes + CREATE OBJECT -o_diff + EXPORTING + iv_new = -data + iv_old = -file-data. + ELSE. " Local leading changes or both were modified + CREATE OBJECT -o_diff + EXPORTING + iv_new = -file-data + iv_old = -data. + ENDIF. ENDIF. ENDMETHOD. "append_diff + METHOD is_binary. + + DATA: lv_len TYPE i, + lv_idx TYPE i, + lv_x TYPE x. + + FIELD-SYMBOLS LIKE iv_d1. + + IF iv_d1 IS NOT INITIAL. " One of them might be new and so empty + ASSIGN iv_d1 TO . + ELSE. + ASSIGN iv_d2 TO . + ENDIF. + + lv_len = xstrlen( ). + IF lv_len = 0. + RETURN. + ENDIF. + + IF lv_len > 100. + lv_len = 100. + ENDIF. + + " Simple char range test + " stackoverflow.com/questions/277521/how-to-identify-the-file-content-as-ascii-or-binary + DO lv_len TIMES. " I'm sure there is more efficient way ... + lv_idx = sy-index - 1. + lv_x = +lv_idx(1). + + IF NOT ( lv_x BETWEEN 9 AND 13 OR lv_x BETWEEN 32 AND 126 ). + rv_yes = abap_true. + EXIT. + ENDIF. + ENDDO. + + ENDMETHOD. " is_binary. + METHOD build_menu. DATA: lo_sub TYPE REF TO lcl_html_toolbar, @@ -237,7 +293,14 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. CREATE OBJECT ro_menu. - IF lines( lt_types ) + lines( lt_users ) > 1. + IF iv_supress_stage = abap_false. + ro_menu->add( iv_txt = 'Stage' + iv_act = |{ gc_action-go_stage }?{ mv_repo_key }| + iv_id = 'stage-button' + iv_opt = gc_html_opt-strong ). + ENDIF. + + IF lines( lt_types ) > 1 OR lines( lt_users ) > 1. CREATE OBJECT lo_sub EXPORTING iv_id = 'diff-filter'. " File types @@ -295,7 +358,7 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. CREATE OBJECT ro_html. - ro_html->add( '
    ' ). + ro_html->add( |
    | ). ro_html->add( lcl_gui_chunk_lib=>render_js_error_banner( ) ). LOOP AT mt_diff_files INTO ls_diff_file. lcl_progress=>show( iv_key = 'Diff' @@ -314,16 +377,24 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. CREATE OBJECT ro_html. ro_html->add( |
    | ). "#EC NOTEXT + }" data-changed-by="{ is_diff-changed_by + }" data-file="{ is_diff-path && is_diff-filename }">| ). "#EC NOTEXT ro_html->add( render_diff_head( is_diff ) ). " Content - ro_html->add( '
    ' ). "#EC NOTEXT - ro_html->add( '' ). "#EC NOTEXT - ro_html->add( render_table_head( ) ). - ro_html->add( render_lines( is_diff ) ). - ro_html->add( '
    ' ). "#EC NOTEXT - ro_html->add( '
    ' ). "#EC NOTEXT + IF is_diff-type <> 'binary'. + ro_html->add( '
    ' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( render_table_head( ) ). + ro_html->add( render_lines( is_diff ) ). + ro_html->add( '
    ' ). "#EC NOTEXT + ro_html->add( '
    ' ). "#EC NOTEXT + ELSE. + ro_html->add( '
    ' ). "#EC NOTEXT + ro_html->add( 'The content seems to be binary.' ). "#EC NOTEXT + ro_html->add( 'Cannot display as diff.' ). "#EC NOTEXT + ro_html->add( '
    ' ). "#EC NOTEXT + ENDIF. ro_html->add( '
    ' ). "#EC NOTEXT @@ -338,21 +409,25 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. DATA: ls_stats TYPE lcl_diff=>ty_count. CREATE OBJECT ro_html. - ls_stats = is_diff-o_diff->stats( ). - - IF is_diff-fstate = c_fstate-both. " Merge stats into 'update' if both were changed - ls_stats-update = ls_stats-update + ls_stats-insert + ls_stats-delete. - CLEAR: ls_stats-insert, ls_stats-delete. - ENDIF. ro_html->add( '
    ' ). "#EC NOTEXT - ro_html->add( |+ { ls_stats-insert }| ). - ro_html->add( |- { ls_stats-delete }| ). - ro_html->add( |~ { ls_stats-update }| ). + IF is_diff-type <> 'binary'. + ls_stats = is_diff-o_diff->stats( ). + IF is_diff-fstate = c_fstate-both. " Merge stats into 'update' if both were changed + ls_stats-update = ls_stats-update + ls_stats-insert + ls_stats-delete. + CLEAR: ls_stats-insert, ls_stats-delete. + ENDIF. + + ro_html->add( |+ { ls_stats-insert }| ). + ro_html->add( |- { ls_stats-delete }| ). + ro_html->add( |~ { ls_stats-update }| ). + ENDIF. + ro_html->add( |{ is_diff-filename }| ). "#EC NOTEXT - ro_html->add( lcl_gui_chunk_lib=>render_item_state( iv1 = is_diff-lstate - iv2 = is_diff-rstate ) ). + ro_html->add( lcl_gui_chunk_lib=>render_item_state( + iv1 = is_diff-lstate + iv2 = is_diff-rstate ) ). IF is_diff-fstate = c_fstate-both AND mv_unified = abap_true. ro_html->add( 'Attention: Unified mode' @@ -571,10 +646,12 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. CREATE OBJECT ro_html. ro_html->add( 'var gHelper = new DiffHelper({' ). - ro_html->add( | seed: "diff{ mv_ts }",| ). + ro_html->add( | seed: "{ mv_seed }",| ). + ro_html->add( | stageAction: "{ gc_action-go_stage }",| ). ro_html->add( ' ids: {' ). - ro_html->add( ' diffList: "diff-list",' ). - ro_html->add( ' filterMenu: "diff-filter" ' ). + ro_html->add( ' diffList: "diff-list",' ). + ro_html->add( ' filterMenu: "diff-filter",' ). + ro_html->add( ' stageButton: "stage-button"' ). ro_html->add( ' }' ). ro_html->add( '});' ). diff --git a/src/zabapgit_page_stage.prog.abap b/src/zabapgit_page_stage.prog.abap index 32098bace..5eb5575c3 100644 --- a/src/zabapgit_page_stage.prog.abap +++ b/src/zabapgit_page_stage.prog.abap @@ -13,7 +13,8 @@ CLASS lcl_gui_page_stage DEFINITION FINAL INHERITING FROM lcl_gui_page. METHODS: constructor IMPORTING - io_repo TYPE REF TO lcl_repo_online + io_repo TYPE REF TO lcl_repo_online + iv_seed TYPE string OPTIONAL RAISING lcx_exception, lif_gui_page~on_event REDEFINITION. @@ -25,8 +26,7 @@ CLASS lcl_gui_page_stage DEFINITION FINAL INHERITING FROM lcl_gui_page. PRIVATE SECTION. DATA: mo_repo TYPE REF TO lcl_repo_online, ms_files TYPE ty_stage_files, - mo_stage TYPE REF TO lcl_stage, - mv_ts TYPE timestamp. + mv_seed TYPE string. METHODS: render_list @@ -47,6 +47,7 @@ CLASS lcl_gui_page_stage DEFINITION FINAL INHERITING FROM lcl_gui_page. process_stage_list IMPORTING it_postdata TYPE cnht_post_data_tab + io_stage TYPE REF TO lcl_stage RAISING lcx_exception, build_menu @@ -58,18 +59,19 @@ CLASS lcl_gui_page_stage IMPLEMENTATION. METHOD constructor. + DATA lv_ts TYPE timestamp. + super->constructor( ). ms_control-page_title = 'STAGE'. mo_repo = io_repo. ms_files = lcl_stage_logic=>get( mo_repo ). + mv_seed = iv_seed. - CREATE OBJECT mo_stage - EXPORTING - iv_branch_name = io_repo->get_branch_name( ) - iv_branch_sha1 = io_repo->get_sha1_remote( ). - - GET TIME STAMP FIELD mv_ts. + IF mv_seed IS INITIAL. + GET TIME STAMP FIELD lv_ts. + mv_seed = |stage{ lv_ts }|. + ENDIF. ms_control-page_menu = build_menu( ). @@ -88,19 +90,24 @@ CLASS lcl_gui_page_stage IMPLEMENTATION. METHOD lif_gui_page~on_event. + DATA lo_stage TYPE REF TO lcl_stage. + FIELD-SYMBOLS: LIKE LINE OF ms_files-local. + CREATE OBJECT lo_stage + EXPORTING + iv_branch_name = mo_repo->get_branch_name( ) + iv_branch_sha1 = mo_repo->get_sha1_remote( ). + CASE iv_action. WHEN c_action-stage_all. - mo_stage->reset_all( ). LOOP AT ms_files-local ASSIGNING . - mo_stage->add( iv_path = -file-path + lo_stage->add( iv_path = -file-path iv_filename = -file-filename iv_data = -file-data ). ENDLOOP. WHEN c_action-stage_commit. - mo_stage->reset_all( ). - process_stage_list( it_postdata ). + process_stage_list( it_postdata = it_postdata io_stage = lo_stage ). WHEN OTHERS. RETURN. ENDCASE. @@ -108,7 +115,7 @@ CLASS lcl_gui_page_stage IMPLEMENTATION. CREATE OBJECT ei_page TYPE lcl_gui_page_commit EXPORTING io_repo = mo_repo - io_stage = mo_stage. + io_stage = lo_stage. ev_state = gc_event_state-new_page. @@ -141,14 +148,14 @@ CLASS lcl_gui_page_stage IMPLEMENTATION. WITH KEY file-path = ls_file-path file-filename = ls_file-filename. ASSERT sy-subrc = 0. - mo_stage->add( iv_path = -file-path + io_stage->add( iv_path = -file-path iv_filename = -file-filename iv_data = -file-data ). WHEN lcl_stage=>c_method-ignore. - mo_stage->ignore( iv_path = ls_file-path + io_stage->ignore( iv_path = ls_file-path iv_filename = ls_file-filename ). WHEN lcl_stage=>c_method-rm. - mo_stage->rm( iv_path = ls_file-path + io_stage->rm( iv_path = ls_file-path iv_filename = ls_file-filename ). WHEN lcl_stage=>c_method-skip. " Do nothing @@ -311,7 +318,7 @@ CLASS lcl_gui_page_stage IMPLEMENTATION. CREATE OBJECT ro_html. ro_html->add( 'var gStageParams = {' ). - ro_html->add( | seed: "stage{ mv_ts }",| ). + ro_html->add( | seed: "{ mv_seed }",| ). ro_html->add( ' formAction: "stage_commit",' ). ro_html->add( ' ids: {' ). diff --git a/src/zabapgit_stage.prog.abap b/src/zabapgit_stage.prog.abap index 2567a3178..25050d028 100644 --- a/src/zabapgit_stage.prog.abap +++ b/src/zabapgit_stage.prog.abap @@ -86,8 +86,8 @@ ENDCLASS. "lcl_stage DEFINITION CLASS lcl_stage IMPLEMENTATION. METHOD constructor. - mv_branch_name = iv_branch_name. - mv_branch_sha1 = iv_branch_sha1. + mv_branch_name = iv_branch_name. + mv_branch_sha1 = iv_branch_sha1. mv_merge_source = iv_merge_source. ENDMETHOD. From 2eb025b0921609bcada17b57747d6cdb0dfbb16d Mon Sep 17 00:00:00 2001 From: larshp Date: Sat, 11 Mar 2017 07:23:25 +0000 Subject: [PATCH 24/28] 72 characters commit body Commit body should wrap at 72 characters as noted in: https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project --- src/zabapgit_page_commit.prog.abap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zabapgit_page_commit.prog.abap b/src/zabapgit_page_commit.prog.abap index 76b10187d..e34a2c293 100644 --- a/src/zabapgit_page_commit.prog.abap +++ b/src/zabapgit_page_commit.prog.abap @@ -193,7 +193,7 @@ CLASS lcl_gui_page_commit IMPLEMENTATION. ro_html->add( render_text_input( iv_name = 'comment' iv_label = 'comment' - iv_max_length = '50' ) ). + iv_max_length = '72' ) ). ro_html->add( '
    ' ). ro_html->add( '' ). From fe6a4c6567b8f780914d0fab52b8995dbb1c87b1 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sat, 11 Mar 2017 11:23:18 +0200 Subject: [PATCH 25/28] page_diff UX: pre-merge fixes --- src/zabapgit_css_common.w3mi.data.css | 1 - src/zabapgit_page_diff.prog.abap | 4 ++-- src/zabapgit_page_stage.prog.abap | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/zabapgit_css_common.w3mi.data.css b/src/zabapgit_css_common.w3mi.data.css index 9068ba7ab..a3becc70a 100644 --- a/src/zabapgit_css_common.w3mi.data.css +++ b/src/zabapgit_css_common.w3mi.data.css @@ -184,7 +184,6 @@ table.repo_tab { border: 1px solid #DDD; border-radius: 3px; background: #fff; - margin-top: 0.5em; width: 100%; } .repo_tab td { diff --git a/src/zabapgit_page_diff.prog.abap b/src/zabapgit_page_diff.prog.abap index cef8bd75f..0876d89f9 100644 --- a/src/zabapgit_page_diff.prog.abap +++ b/src/zabapgit_page_diff.prog.abap @@ -48,7 +48,7 @@ CLASS lcl_gui_page_diff DEFINITION FINAL INHERITING FROM lcl_gui_page. mt_delayed_lines TYPE lcl_diff=>ty_diffs_tt, mv_unified TYPE abap_bool VALUE abap_true, mv_repo_key TYPE lcl_persistence_repo=>ty_repo-key, - mv_seed TYPE string. + mv_seed TYPE string. " Unique page id to bind JS sessionStorage METHODS render_diff IMPORTING is_diff TYPE ty_file_diff @@ -105,7 +105,7 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. mv_repo_key = iv_key. GET TIME STAMP FIELD lv_ts. - mv_seed = |diff{ lv_ts }|. + mv_seed = |diff{ lv_ts }|. " Generate based on time ASSERT is_file IS INITIAL OR is_object IS INITIAL. " just one passed diff --git a/src/zabapgit_page_stage.prog.abap b/src/zabapgit_page_stage.prog.abap index 5eb5575c3..8394e2056 100644 --- a/src/zabapgit_page_stage.prog.abap +++ b/src/zabapgit_page_stage.prog.abap @@ -26,7 +26,7 @@ CLASS lcl_gui_page_stage DEFINITION FINAL INHERITING FROM lcl_gui_page. PRIVATE SECTION. DATA: mo_repo TYPE REF TO lcl_repo_online, ms_files TYPE ty_stage_files, - mv_seed TYPE string. + mv_seed TYPE string. " Unique page id to bind JS sessionStorage METHODS: render_list @@ -68,7 +68,7 @@ CLASS lcl_gui_page_stage IMPLEMENTATION. ms_files = lcl_stage_logic=>get( mo_repo ). mv_seed = iv_seed. - IF mv_seed IS INITIAL. + IF mv_seed IS INITIAL. " Generate based on time unless obtained from diff page GET TIME STAMP FIELD lv_ts. mv_seed = |stage{ lv_ts }|. ENDIF. @@ -318,7 +318,7 @@ CLASS lcl_gui_page_stage IMPLEMENTATION. CREATE OBJECT ro_html. ro_html->add( 'var gStageParams = {' ). - ro_html->add( | seed: "{ mv_seed }",| ). + ro_html->add( | seed: "{ mv_seed }",| ). " Unique page id ro_html->add( ' formAction: "stage_commit",' ). ro_html->add( ' ids: {' ). From bc1df00f9a4c2dba8ce92bee398af80287ab003d Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sat, 11 Mar 2017 11:32:56 +0200 Subject: [PATCH 26/28] page_diff UX: pre-merge change font-size back --- src/zabapgit_css_common.w3mi.data.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/zabapgit_css_common.w3mi.data.css b/src/zabapgit_css_common.w3mi.data.css index a3becc70a..db658984d 100644 --- a/src/zabapgit_css_common.w3mi.data.css +++ b/src/zabapgit_css_common.w3mi.data.css @@ -621,7 +621,6 @@ div.tutorial h2 { { display: block; text-decoration: none; - font-size: 11pt; line-height: 30px; padding: 0 12px; } From 45b293c2be76abf069dc16983c575b5ddd6d65f6 Mon Sep 17 00:00:00 2001 From: larshp Date: Sat, 11 Mar 2017 09:39:25 +0000 Subject: [PATCH 27/28] v1.32.0 --- src/zabapgit.prog.abap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zabapgit.prog.abap b/src/zabapgit.prog.abap index 3e1a01f7d..d75202be2 100644 --- a/src/zabapgit.prog.abap +++ b/src/zabapgit.prog.abap @@ -3,7 +3,7 @@ REPORT zabapgit LINE-SIZE 100. * See http://www.abapgit.org CONSTANTS: gc_xml_version TYPE string VALUE 'v1.0.0', "#EC NOTEXT - gc_abap_version TYPE string VALUE 'v1.31.1'. "#EC NOTEXT + gc_abap_version TYPE string VALUE 'v1.32.0'. "#EC NOTEXT ******************************************************************************** * The MIT License (MIT) From 0d4d8ddff1e0aa4ef49b23660811c3f966403196 Mon Sep 17 00:00:00 2001 From: Lars Hvam Date: Sat, 11 Mar 2017 10:40:40 +0100 Subject: [PATCH 28/28] v1.32.0 --- changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/changelog.txt b/changelog.txt index 7829d44e5..cdc50d272 100644 --- a/changelog.txt +++ b/changelog.txt @@ -8,6 +8,12 @@ Legend + : added - : removed +2017-03-07 v1.32.0 +------------------ ++ user interface changed for diff and staging pages +* body length in commit page +! refactored lcl_log + 2017-03-07 v1.31.1 ------------------ ! local .abapgit.xml state, note migration is triggered automatically when executing abapGit