Merge remote-tracking branch 'refs/remotes/larshp/master'

This commit is contained in:
EduardoCopat 2017-03-13 15:17:44 +01:00
commit 552a9d9b84
44 changed files with 1870 additions and 713 deletions

View File

@ -8,6 +8,33 @@ 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
2017-02-25 v1.31.0
------------------
+ SFPF support
+ Committer and author separated
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

View File

@ -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.32.0'. "#EC NOTEXT
********************************************************************************
* The MIT License (MIT)
@ -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.

View File

@ -75,9 +75,9 @@ CLASS lcl_background IMPLEMENTATION.
iv_data = <ls_local>-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( <ls_local>-item ).
ls_comment-email = |{ ls_comment-username }@localhost|.
ls_comment-committer-name = lcl_objects=>changed_by( <ls_local>-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 <ls_local>.
IF lcl_objects=>changed_by( <ls_local>-item ) = ls_comment-username.
IF lcl_objects=>changed_by( <ls_local>-item ) = ls_comment-committer-name.
WRITE: / 'stage' ##NO_TEXT,
ls_comment-username,
ls_comment-committer-name,
<ls_local>-file-path,
<ls_local>-file-filename.

View File

@ -35,10 +35,12 @@ 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; }
.warning { color: #e4ae0d !important; }
.warning { color: #efb301 !important; }
.blue { color: #5e8dc9 !important; }
.red { color: red !important; }
@ -46,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; }
@ -55,58 +58,49 @@ 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.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 div.toc_grid a {
color: #ccc;
}
div#toc:hover div.toc_grid a {
color: #4078c0;
}
div#toc div.toc_row {
margin: 0.3em 0em;
}
div#toc .favorites a { opacity: 0.5; }
div#toc .favorites:hover a { opacity: 1; }
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 */
@ -118,101 +112,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: 16px;
bottom: 0px;
left: -16px;
}
.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;
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;
@ -274,14 +176,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;
@ -290,7 +184,6 @@ table.repo_tab {
border: 1px solid #DDD;
border-radius: 3px;
background: #fff;
margin-top: 0.5em;
width: 100%;
}
.repo_tab td {
@ -408,17 +301,34 @@ input.stage-filter { width: 18em; }
}
/* COMMIT */
div.form_div {
margin: 0.5em 0em;
div.form-container {
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;
@ -439,6 +349,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;
}
@ -682,3 +602,131 @@ div.tutorial h2 {
font-size: 14pt;
color: #404040;
}
/* 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;
position: relative;
float: left;
margin: 0;
padding: 0;
}
.nav-container.float-right ul { float: right; }
.nav-container ul a
{
display: block;
text-decoration: none;
line-height: 30px;
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
{
position: relative;
float: left;
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:hover > ul { display: block; }
.nav-container ul ul li:hover { background-color: #f6f6f6; }
/* 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
{
display: none;
position: absolute;
top: 100%;
left: 0;
z-index: 1;
background: #fff;
padding: 0;
box-shadow: 1px 1px 3px 0px #bbb;
}
.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%;
}
/* 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;
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%;
}
/* 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: 10px;
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; }
/* 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; }

View File

@ -15,7 +15,7 @@
<RELID>MI</RELID>
<OBJID>ZABAPGIT_CSS_COMMON</OBJID>
<NAME>filename</NAME>
<VALUE>common.css</VALUE>
<VALUE>~wwwtmp.css</VALUE>
</WWWPARAMS>
<WWWPARAMS>
<RELID>MI</RELID>

View File

@ -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,
@ -165,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.

View File

@ -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

View File

@ -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,10 +99,9 @@ CLASS lcl_file_status IMPLEMENTATION.
BINARY SEARCH. " Sorted above
IF sy-subrc <> 0 OR <ls_res1>-path <> <ls_res2>-path. " All paths are same
io_log->add( iv_msgv1 = 'Files for object'
iv_msgv2 = <ls_res1>-obj_type
iv_msgv3 = <ls_res1>-obj_name
iv_msgv4 = 'are not placed in the same folder'
io_log->add( iv_msg = |Files for object { <ls_res1>-obj_type }{
<ls_res1>-obj_name }are not placed in the same folder|
iv_type = 'W'
iv_rc = '1' ) ##no_text.
ENDIF.
ENDLOOP.
@ -114,9 +113,9 @@ CLASS lcl_file_status IMPLEMENTATION.
io_dot = io_dot
iv_package = <ls_res1>-package ).
IF lv_path <> <ls_res1>-path.
io_log->add( iv_msgv1 = 'Package and path does not match for object,'
iv_msgv2 = <ls_res1>-obj_type
iv_msgv3 = <ls_res1>-obj_name
io_log->add( iv_msg = |Package and path does not match for object, {
<ls_res1>-obj_type } { <ls_res1>-obj_name }|
iv_type = 'W'
iv_rc = '2' ) ##no_text.
ENDIF.
ENDLOOP.
@ -126,16 +125,15 @@ CLASS lcl_file_status IMPLEMENTATION.
LOOP AT lt_res_sort ASSIGNING <ls_res1>.
IF <ls_res1>-filename IS NOT INITIAL AND <ls_res1>-filename = ls_file-filename.
io_log->add( iv_msgv1 = 'Multiple files with same filename,'
iv_msgv2 = <ls_res1>-filename
iv_rc = '3' ) ##no_text.
io_log->add( iv_msg = |Multiple files with same filename, { <ls_res1>-filename }|
iv_type = 'W'
iv_rc = '3' ) ##no_text.
ENDIF.
IF <ls_res1>-filename IS INITIAL.
io_log->add( iv_msgv1 = 'Filename is empty for object'
iv_msgv2 = <ls_res1>-obj_type
iv_msgv3 = <ls_res1>-obj_name
iv_rc = '4' ) ##no_text.
io_log->add( iv_msg = |Filename is empty for object { <ls_res1>-obj_type } { <ls_res1>-obj_name }|
iv_type = 'W'
iv_rc = '4' ) ##no_text.
ENDIF.
MOVE-CORRESPONDING <ls_res1> TO ls_file.
@ -254,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.

View File

@ -37,6 +37,9 @@ CLASS lcl_folder_logic IMPLEMENTATION.
lv_length = strlen( io_dot->get_starting_folder( ) ).
IF lv_length > strlen( iv_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 ).

View File

@ -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 = <ls_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 ).

View File

@ -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.

View File

@ -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 = |<a{ lv_id }{ lv_class }{ lv_href }{ lv_style }>{ iv_txt }</a>|.
rv_str = |<a{ lv_id }{ lv_class }{ lv_href }{ lv_click }{ lv_style }>{ iv_txt }</a>|.
ENDMETHOD. "a
@ -371,41 +376,64 @@ CLASS lcl_html_toolbar DEFINITION FINAL.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
iv_id TYPE string OPTIONAL,
add
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_cur TYPE abap_bool OPTIONAL
iv_opt TYPE c OPTIONAL
iv_typ TYPE c DEFAULT gc_action_type-sapevent,
iv_chk TYPE abap_bool DEFAULT abap_undefined
iv_aux TYPE string OPTIONAL
iv_id TYPE string 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_with_icons 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_corner 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,
chk TYPE abap_bool,
aux TYPE string,
id 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:
render_items
IMPORTING
iv_sort TYPE abap_bool OPTIONAL
RETURNING
VALUE(ro_html) TYPE REF TO lcl_html.
ENDCLASS. "lcl_html_toolbar DEFINITION
@ -414,6 +442,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.
@ -421,8 +453,13 @@ 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
ASSERT NOT ( iv_chk <> abap_undefined AND io_sub IS NOT INITIAL ).
ls_item-txt = iv_txt.
ls_item-act = iv_act.
@ -430,96 +467,139 @@ 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.
ls_item-chk = iv_chk.
ls_item-aux = iv_aux.
ls_item-id = iv_id.
APPEND ls_item TO mt_items.
ENDMETHOD. "add
METHOD render. "TODO refactor
DATA: lv_class TYPE string,
lv_is_drop TYPE abap_bool.
FIELD-SYMBOLS <ls_item> 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( |<div class="{ lv_class }">| ).
ro_html->add( render_items( iv_sort = iv_sort ) ).
ro_html->add( '</div>' ).
IF lv_is_drop = abap_true. " Dropdown
IF iv_as_angle = abap_true.
ro_html->add( '<div class="dropbtn_angle"></div>' ).
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( '<div class="minizone"></div>' ).
ENDIF.
METHOD render_as_droplist.
ro_html->add( '<div class="dropdown_content">' ).
ro_html->add( '<div class="box">' ).
DATA: lv_class TYPE string.
CREATE OBJECT ro_html.
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( |<div class="{ lv_class }">| ).
ro_html->add( '<ul><li>' ).
ro_html->add_a( iv_txt = iv_label
iv_typ = gc_action_type-dummy
iv_act = '' ).
ro_html->add( '<div class="minizone"></div>' ).
ro_html->add( render_items( iv_sort = iv_sort ) ).
ro_html->add( '</li></ul>' ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_as_droplist
METHOD render_items.
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 <item> LIKE LINE OF mt_items.
CREATE OBJECT ro_html.
IF iv_sort = abap_true.
SORT mt_items BY txt ASCENDING AS TEXT.
ENDIF.
IF iv_with_icons = abap_true.
ro_html->add( '<table>' ).
" Check has icons or check boxes
LOOP AT mt_items ASSIGNING <item> WHERE ico IS NOT INITIAL OR chk <> abap_undefined.
lv_has_icons = abap_true.
lv_class = ' class="with-icons"'.
EXIT.
ENDLOOP.
IF mv_id IS NOT INITIAL.
lv_id = | id="{ mv_id }"|.
ENDIF.
LOOP AT mt_items ASSIGNING <ls_item>.
ro_html->add( |<ul{ lv_id }{ lv_class }>| ).
IF <ls_item>-sub IS INITIAL.
" Render items
LOOP AT mt_items ASSIGNING <item>.
CLEAR: lv_class, lv_icon.
IF iv_with_icons = abap_true.
ro_html->add( '<tr>' ).
ro_html->add( |<td class="icon">{ lcl_html=>icon( <ls_item>-ico ) }</td>| ).
ro_html->add( '<td class="text">' ).
ENDIF.
ro_html->add_a( iv_txt = <ls_item>-txt
iv_act = <ls_item>-act
iv_opt = <ls_item>-opt
iv_typ = <ls_item>-typ ).
IF iv_with_icons = abap_true.
ro_html->add( '</td>' ).
ro_html->add( '</tr>' ).
ENDIF.
ELSE.
ro_html->add( <ls_item>-sub->render( iv_as_droplist_with_label = <ls_item>-txt ) ).
IF <item>-typ = gc_action_type-separator.
ro_html->add( |<li class="separator">{ <item>-txt }</li>| ).
CONTINUE.
ENDIF.
IF lv_has_icons = abap_true.
IF <item>-chk = abap_true.
lv_icon = lcl_html=>icon( 'check/blue' ).
lv_check = ' data-check="X"'.
ELSEIF <item>-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( <item>-ico ).
ENDIF.
ENDIF.
IF <item>-cur = abap_true.
lv_class = ' class="current-menu-item"'.
ENDIF.
IF <item>-aux IS NOT INITIAL.
lv_aux = | data-aux="{ <item>-aux }"|.
ENDIF.
ro_html->add( |<li{ lv_class }{ lv_check }{ lv_aux }>| ).
IF <item>-sub IS INITIAL.
ro_html->add_a( iv_txt = lv_icon && <item>-txt
iv_typ = <item>-typ
iv_act = <item>-act
iv_id = <item>-id
iv_opt = <item>-opt ).
ELSE.
ro_html->add_a( iv_txt = lv_icon && <item>-txt
iv_typ = gc_action_type-dummy
iv_act = ''
iv_id = <item>-id
iv_opt = <item>-opt ).
ro_html->add( <item>-sub->render_items( iv_sort = iv_sort ) ).
ENDIF.
ro_html->add( '</li>' ).
ENDLOOP.
IF iv_with_icons = abap_true.
ro_html->add( '</table>' ).
ENDIF.
ro_html->add( '</ul>' ).
IF lv_is_drop = abap_true. " Dropdown
ro_html->add( '</div>' ).
ro_html->add( '</div>' ).
ENDIF.
ENDMETHOD. "render_items
ro_html->add( '</div>' ).
ENDMETHOD. "render
ENDCLASS. "lcl_html_toolbar IMPLEMENTATION

View File

@ -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,14 +303,14 @@ 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 = '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 <body>.
ASSERT <body> IS ASSIGNED.
@ -311,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 ).
@ -326,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

View File

@ -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

View File

@ -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
@ -363,3 +364,138 @@ StageHelper.prototype.iterateStageTab = function (changeMode, cb /*, ...*/) {
window.scrollTo(0, scrollOffset);
}
}
/**********************************************************
* Check list wrapper
**********************************************************/
function CheckListWrapper(id, cbAction) {
this.id = document.getElementById(id);
this.cbAction = cbAction;
this.id.onclick = this.onClick.bind(this);
}
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);
}
/**********************************************************
* Diff page logic
**********************************************************/
// Diff helper constructor
function DiffHelper(params) {
this.pageSeed = params.seed;
this.counter = 0;
this.stageAction = params.stageAction;
// DOM nodes
this.dom = {
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
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) {
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;
if (this.counter > 0) {
this.dom.filterButton.classList.add("bgorange");
} else {
this.dom.filterButton.classList.remove("bgorange");
}
};

View File

@ -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: <lo_repo> LIKE LINE OF lt_repos.
lt_repos = lcl_app=>repo_srv( )->list( ).
LOOP AT lt_repos ASSIGNING <lo_repo>.
lo_dot_abapgit = <lo_repo>->get_dot_abapgit( ).
IF lo_dot_abapgit->get_data( ) IS INITIAL.
IF <lo_repo>->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.
<lo_repo>->refresh( ).
lo_dot_abapgit = <lo_repo>->find_remote_dot_abapgit( ).
ENDIF.
<lo_repo>->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.

View File

@ -448,6 +448,9 @@ CLASS lcl_object_fugr IMPLEMENTATION.
DELETE TABLE rt_includes FROM <ls_func>-include.
ENDLOOP.
* handle generated maintenance views
APPEND INITIAL LINE TO rt_includes ASSIGNING <lv_include>.
<lv_include> = |L{ ms_item-obj_name }T00|.
LOOP AT rt_includes ASSIGNING <lv_include>.
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.

View File

@ -29,6 +29,8 @@ 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.
INCLUDE zabapgit_object_shlp.

View File

@ -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

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_PROG" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<PROGDIR>
<NAME>ZABAPGIT_OBJECT_SFPF</NAME>
<STATE>A</STATE>
<VARCL>X</VARCL>
<SUBC>I</SUBC>
<RLOAD>E</RLOAD>
<UCCHECK>X</UCCHECK>
</PROGDIR>
<TPOOL>
<item>
<ID>R</ID>
<ENTRY>Include ZABAPGIT_OBJECT_DOMA</ENTRY>
<LENGTH>28</LENGTH>
</item>
</TPOOL>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -0,0 +1,169 @@
*&---------------------------------------------------------------------*
*& 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 ).
lcl_object_sfpf=>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_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

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_PROG" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<PROGDIR>
<NAME>ZABAPGIT_OBJECT_SFPI</NAME>
<STATE>A</STATE>
<VARCL>X</VARCL>
<SUBC>I</SUBC>
<RLOAD>E</RLOAD>
<UCCHECK>X</UCCHECK>
</PROGDIR>
<TPOOL>
<item>
<ID>R</ID>
<ENTRY>Include ZABAPGIT_OBJECT_DOMA</ENTRY>
<LENGTH>28</LENGTH>
</item>
</TPOOL>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -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 ).

View File

@ -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

View File

@ -481,10 +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_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.

View File

@ -94,13 +94,13 @@ CLASS lcl_gui_page IMPLEMENTATION.
iv_act = gc_action-abapgit_home )
}</td>| ). "#EC NOTEXT
ro_html->add( |<td class="headpad"><span class="page_title"> &#x25BA; {
ro_html->add( |<td><span class="page_title"> &#x25BA; {
ms_control-page_title
}</span></td>| ). "#EC NOTEXT
IF ms_control-page_menu IS BOUND.
ro_html->add( '<td class="headpad right">' ). "#EC NOTEXT
ro_html->add( ms_control-page_menu->render( ) ).
ro_html->add( '<td class="right">' ). "#EC NOTEXT
ro_html->add( ms_control-page_menu->render( iv_right = abap_true ) ).
ro_html->add( '</td>' ). "#EC NOTEXT
ENDIF.

View File

@ -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( '<div class="row">' ).
ro_html->add( |<label for="{ iv_name }">{ iv_label }</label>| ).
ro_html->add( |<input id="{ iv_name }" name="{ iv_name }" type="text"{ lv_attrs }>| ).
ro_html->add( '</div>' ).
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( '<div class="form_div">' ).
ro_html->add( '<form id="commit_form" method="post" action="sapevent:commit_post">' ).
ro_html->add( |<input name="repo_key" type="hidden" value="{ lv_key }">| ).
ro_html->add( '<table>' ).
ro_html->add( '<div class="form-container">' ).
ro_html->add( '<form id="commit_form" class="aligned-form"'
&& ' method="post" action="sapevent:commit_post">' ).
ro_html->add( '<tr>' ).
ro_html->add( '<td class="field_name">username</td>' ).
ro_html->add( '<td>' ).
ro_html->add( |<input name="username" type="text" size="50" value="{ lv_user }">| ).
ro_html->add( '</td>' ).
ro_html->add( '</tr>' ).
ro_html->add( render_text_input( iv_name = 'committer_name'
iv_label = 'committer name'
iv_value = lv_user ) ).
ro_html->add( '<tr>' ).
ro_html->add( '<td class="field_name">email</td>' ).
ro_html->add( '<td>' ).
ro_html->add( |<input name="email" type="text" size="50" value="{ lv_email }">| ).
ro_html->add( '</td>' ).
ro_html->add( '</tr>' ).
ro_html->add( render_text_input( iv_name = 'committer_email'
iv_label = 'committer e-mail'
iv_value = lv_email ) ).
ro_html->add( '<tr>' ).
ro_html->add( '<td class="field_name">comment</td>' ).
ro_html->add( '<td>' ).
ro_html->add(
'<input name="comment" type="text" id="commit_msg" maxlength="50" size="50">' ).
ro_html->add( '</td>' ).
ro_html->add( '</tr>' ).
ro_html->add( render_text_input( iv_name = 'comment'
iv_label = 'comment'
iv_max_length = '72' ) ).
ro_html->add( '<tr>' ).
ro_html->add( '<td class="field_name">body</td>' ).
ro_html->add( '<td>' ).
ro_html->add( '<textarea name="body" rows="10" cols="50"></textarea>' ).
ro_html->add( '<div class="row">' ).
ro_html->add( '<label for="c-body">body</label>' ).
ro_html->add( '<textarea id="c-body" name="body" rows="10" cols="50"></textarea>' ).
ro_html->add( '<input type="submit" class="hidden-submit">' ).
ro_html->add( '</div>' ).
ro_html->add( '<input type="submit" class="hidden-submit">' ). "Hmmm ... reconsider
ro_html->add( '<div class="row">' ).
ro_html->add( '<span class="cell"></span>' ).
ro_html->add( '<span class="cell sub-title">Optionally,'
&& ' specify author (same as committer by default)</span>' ).
ro_html->add( '</div>' ).
ro_html->add( '</td>' ).
ro_html->add( '</tr>' ).
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( '</table>' ).
ro_html->add( '</form>' ).
ro_html->add( '</div>' ).
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

View File

@ -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 = |<table class="tag"><tr><td class="label">Type:</td>|
&& | <td>{ is_key-type }</td></tr></table>|
&& gc_newline
&& |<table class="tag"><tr><td class="label">Key:</td>|
&& | <td>{ is_key-value }</td></tr></table>|.
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( '<div class="db_entry">' ).
ro_html->add( '<table class="toolbar"><tr><td>' ).
ro_html->add( |<table class="tag"><tr><td class="label">Type:</td>| &&
| <td>{ ms_key-type }</td></tr></table>| ).
ro_html->add( |<table class="tag"><tr><td class="label">Key:</td>| &&
| <td>{ ms_key-value }</td></tr></table>| ).
ro_html->add( '</td><td class="right">' ).
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( '</td><td>' ).
ro_html->add( lo_toolbar->render( iv_right = abap_true ) ).
ro_html->add( '</td></tr></table>' ).
ro_html->add( |<pre class="syntax-hl">{ lv_data }</pre>| ).
@ -111,32 +122,26 @@ CLASS lcl_gui_page_db_edit IMPLEMENTATION.
CREATE OBJECT ro_html.
CREATE OBJECT lo_toolbar.
ro_html->add( '<div class="db_entry">' ).
" Banners
ro_html->add( |<table class="tag"><tr><td class="label">Type:</td>| &&
| <td>{ ms_key-type }</td></tr></table>| ).
ro_html->add( |<table class="tag"><tr><td class="label">Key:</td>| &&
| <td>{ ms_key-value }</td></tr></table>| ).
" Form
ro_html->add( |<form id="db_form" method="post" action="sapevent:{ gc_action-db_update }">| ).
ro_html->add( |<input type="hidden" name="type" value="{ ms_key-type }">| ).
ro_html->add( |<input type="hidden" name="value" value="{ ms_key-value }">| ).
ro_html->add( |<textarea rows="20" cols="100" name="xmldata">{ lv_data
}</textarea>| ).
ro_html->add( '</form>' ).
" 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( '<div class="paddings">' ).
ro_html->add( lo_toolbar->render( ) ).
ro_html->add( '</div>' ).
ro_html->add( '<div class="db_entry">' ).
" Banners & Toolbar
ro_html->add( '<table class="toolbar"><tr><td>' ).
ro_html->add( lcl_gui_page_db_display=>render_record_banner( ms_key ) ).
ro_html->add( '</td><td>' ).
ro_html->add( lo_toolbar->render( iv_right = abap_true ) ).
ro_html->add( '</td></tr></table>' ).
" Form
ro_html->add( |<form id="db_form" method="post" action="sapevent:{ gc_action-db_update }">| ).
ro_html->add( |<input type="hidden" name="type" value="{ ms_key-type }">| ).
ro_html->add( |<input type="hidden" name="value" value="{ ms_key-value }">| ).
ro_html->add( |<textarea rows="20" cols="100" name="xmldata">{ lv_data }</textarea>| ).
ro_html->add( '</form>' ).
ro_html->add( '</div>' ). "db_entry
@ -214,7 +219,7 @@ CLASS lcl_gui_page_db IMPLEMENTATION.
ro_html->add( |<td>{ <ls_data>-value }</td>| ).
ro_html->add( |<td class="data">{ explain_content( <ls_data> ) }</td>| ).
ro_html->add( '<td>' ).
ro_html->add( lo_toolbar->render( iv_vertical = abap_false ) ).
ro_html->add( lo_toolbar->render( ) ).
ro_html->add( '</td>' ).
ro_html->add( '</tr>' ).
ENDLOOP.

View File

@ -14,24 +14,30 @@ 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,
path TYPE string,
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.
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.
PROTECTED SECTION.
METHODS render_content REDEFINITION.
METHODS:
render_content REDEFINITION,
scripts REDEFINITION.
PRIVATE SECTION.
CONSTANTS: BEGIN OF c_actions,
@ -40,7 +46,9 @@ 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_repo_key TYPE lcl_persistence_repo=>ty_repo-key,
mv_seed TYPE string. " Unique page id to bind JS sessionStorage
METHODS render_diff
IMPORTING is_diff TYPE ty_file_diff
@ -70,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
@ -81,14 +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: <ls_status> LIKE LINE OF lt_status.
super->constructor( ).
ms_control-page_title = 'DIFF'.
ms_control-page_menu = build_menu( ).
mv_unified = lcl_app=>user( )->get_diff_unified( ).
mv_repo_key = iv_key.
GET TIME STAMP FIELD lv_ts.
mv_seed = |diff{ lv_ts }|. " Generate based on time
ASSERT is_file IS INITIAL OR is_object IS INITIAL. " just one passed
@ -131,11 +148,14 @@ CLASS lcl_gui_page_diff IMPLEMENTATION.
lcx_exception=>raise( 'PAGE_DIFF ERROR: No diff files found' ).
ENDIF.
ms_control-page_menu = build_menu( iv_supress_stage ).
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.
@ -163,6 +183,7 @@ CLASS lcl_gui_page_diff IMPLEMENTATION.
ENDIF.
APPEND INITIAL LINE TO mt_diff_files ASSIGNING <ls_diff>.
<ls_diff>-path = is_status-path.
<ls_diff>-filename = is_status-filename.
<ls_diff>-lstate = is_status-lstate.
<ls_diff>-rstate = is_status-rstate.
@ -175,24 +196,142 @@ CLASS lcl_gui_page_diff IMPLEMENTATION.
<ls_diff>-fstate = c_fstate-remote.
ENDIF.
IF <ls_diff>-fstate = c_fstate-remote. " Remote file leading changes
CREATE OBJECT <ls_diff>-o_diff
EXPORTING
iv_new = <ls_remote>-data
iv_old = <ls_local>-file-data.
ELSE. " Local leading changes or both were modified
CREATE OBJECT <ls_diff>-o_diff
EXPORTING
iv_new = <ls_local>-file-data
iv_old = <ls_remote>-data.
" Changed by
IF <ls_local>-item-obj_type IS NOT INITIAL.
<ls_diff>-changed_by = to_lower( lcl_objects=>changed_by( <ls_local>-item ) ).
ENDIF.
" Extension
IF <ls_local>-file-filename IS NOT INITIAL.
<ls_diff>-type = reverse( <ls_local>-file-filename ).
ELSE.
<ls_diff>-type = reverse( <ls_remote>-filename ).
ENDIF.
FIND FIRST OCCURRENCE OF '.' IN <ls_diff>-type MATCH OFFSET lv_offs.
<ls_diff>-type = reverse( substring( val = <ls_diff>-type len = lv_offs ) ).
IF <ls_diff>-type <> 'xml' AND <ls_diff>-type <> 'abap'.
<ls_diff>-type = 'other'.
ENDIF.
IF <ls_diff>-type = 'other'
AND is_binary( iv_d1 = <ls_remote>-data iv_d2 = <ls_local>-file-data ) = abap_true.
<ls_diff>-type = 'binary'.
ENDIF.
" Diff data
IF <ls_diff>-type <> 'binary'.
IF <ls_diff>-fstate = c_fstate-remote. " Remote file leading changes
CREATE OBJECT <ls_diff>-o_diff
EXPORTING
iv_new = <ls_remote>-data
iv_old = <ls_local>-file-data.
ELSE. " Local leading changes or both were modified
CREATE OBJECT <ls_diff>-o_diff
EXPORTING
iv_new = <ls_local>-file-data
iv_old = <ls_remote>-data.
ENDIF.
ENDIF.
ENDMETHOD. "append_diff
METHOD is_binary.
DATA: lv_len TYPE i,
lv_idx TYPE i,
lv_x TYPE x.
FIELD-SYMBOLS <data> LIKE iv_d1.
IF iv_d1 IS NOT INITIAL. " One of them might be new and so empty
ASSIGN iv_d1 TO <data>.
ELSE.
ASSIGN iv_d2 TO <data>.
ENDIF.
lv_len = xstrlen( <data> ).
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 = <data>+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,
lt_types TYPE string_table,
lt_users TYPE string_table.
FIELD-SYMBOLS: <diff> LIKE LINE OF mt_diff_files,
<i> TYPE string.
" Get unique
LOOP AT mt_diff_files ASSIGNING <diff>.
APPEND <diff>-type TO lt_types.
APPEND <diff>-changed_by TO lt_users.
ENDLOOP.
SORT: lt_types, lt_users.
DELETE ADJACENT DUPLICATES FROM: lt_types, lt_users.
CREATE OBJECT ro_menu.
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
IF lines( lt_types ) > 1.
lo_sub->add( iv_txt = 'TYPE' iv_typ = gc_action_type-separator ).
LOOP AT lt_types ASSIGNING <i>.
lo_sub->add( iv_txt = <i>
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 <i>.
lo_sub->add( iv_txt = <i>
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.
ro_menu->add( iv_txt = 'Split/Unified view'
iv_act = c_actions-toggle_unified ) ##NO_TEXT.
ENDMETHOD. " build_menu.
**********************************************************************
@ -219,6 +358,8 @@ CLASS lcl_gui_page_diff IMPLEMENTATION.
CREATE OBJECT ro_html.
ro_html->add( |<div id="diff-list" data-repo-key="{ mv_repo_key }">| ).
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
@ -227,6 +368,7 @@ CLASS lcl_gui_page_diff IMPLEMENTATION.
ro_html->add( render_diff( ls_diff_file ) ).
ENDLOOP.
ro_html->add( '</div>' ).
ENDMETHOD. "render_content
@ -234,16 +376,25 @@ CLASS lcl_gui_page_diff IMPLEMENTATION.
CREATE OBJECT ro_html.
ro_html->add( '<div class="diff">' ). "#EC NOTEXT
ro_html->add( |<div class="diff" data-type="{ is_diff-type
}" 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( '<div class="diff_content">' ). "#EC NOTEXT
ro_html->add( '<table class="diff_tab syntax-hl">' ). "#EC NOTEXT
ro_html->add( render_table_head( ) ).
ro_html->add( render_lines( is_diff ) ).
ro_html->add( '</table>' ). "#EC NOTEXT
ro_html->add( '</div>' ). "#EC NOTEXT
IF is_diff-type <> 'binary'.
ro_html->add( '<div class="diff_content">' ). "#EC NOTEXT
ro_html->add( '<table class="diff_tab syntax-hl">' ). "#EC NOTEXT
ro_html->add( render_table_head( ) ).
ro_html->add( render_lines( is_diff ) ).
ro_html->add( '</table>' ). "#EC NOTEXT
ro_html->add( '</div>' ). "#EC NOTEXT
ELSE.
ro_html->add( '<div class="diff_content paddings center grey">' ). "#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( '</div>' ). "#EC NOTEXT
ENDIF.
ro_html->add( '</div>' ). "#EC NOTEXT
@ -258,27 +409,34 @@ 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( '<div class="diff_head">' ). "#EC NOTEXT
ro_html->add( |<span class="diff_banner diff_ins">+ { ls_stats-insert }</span>| ).
ro_html->add( |<span class="diff_banner diff_del">- { ls_stats-delete }</span>| ).
ro_html->add( |<span class="diff_banner diff_upd">~ { ls_stats-update }</span>| ).
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( |<span class="diff_banner diff_ins">+ { ls_stats-insert }</span>| ).
ro_html->add( |<span class="diff_banner diff_del">- { ls_stats-delete }</span>| ).
ro_html->add( |<span class="diff_banner diff_upd">~ { ls_stats-update }</span>| ).
ENDIF.
ro_html->add( |<span class="diff_name">{ is_diff-filename }</span>| ). "#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( '<span class="attention pad-sides">Attention: Unified mode'
&& ' highlighting for MM assumes local file is newer ! </span>' ). "#EC NOTEXT
ENDIF.
ro_html->add( |<span class="diff_changed_by">last change by: <span class="user">{
is_diff-changed_by }</span></span>| ).
ro_html->add( '</div>' ). "#EC NOTEXT
ENDMETHOD.
@ -483,4 +641,19 @@ 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: "{ 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( ' stageButton: "stage-button"' ).
ro_html->add( ' }' ).
ro_html->add( '});' ).
ENDMETHOD. "scripts
ENDCLASS. "lcl_gui_page_diff

View File

@ -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_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,11 +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_key = lo_repo->get_key( ).
lv_current = abap_false.
IF lv_key = mv_show.
lv_opt = gc_html_opt-strong.
ELSE.
CLEAR lv_opt.
lv_current = 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_current ).
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_current ).
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' )
}</td>| ).
ro_html->add( '<td class="pad-sides w100">' ). " Maximize width
ro_html->add( '<td class="pad-sides w100 favorites">' ). " Maximize width
IF lo_favbar->count( ) > 0.
ro_html->add( lo_favbar->render( iv_sort = abap_true ) ).
ELSE.
@ -288,12 +287,11 @@ CLASS lcl_gui_page_main IMPLEMENTATION.
ENDIF.
ro_html->add( '</td>' ).
ro_html->add( '<td class="right">' ).
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( '<td>' ).
ro_html->add( lo_allbar->render_as_droplist(
iv_label = lcl_html=>icon( iv_name = 'three-bars/blue' )
iv_right = abap_true
iv_sort = abap_true ) ).
ro_html->add( '</td>' ).
ro_html->add( '</tr></table>' ).

View File

@ -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. " Unique page id to bind JS sessionStorage
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. " Generate based on time unless obtained from diff page
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: <ls_file> 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 <ls_file>.
mo_stage->add( iv_path = <ls_file>-file-path
lo_stage->add( iv_path = <ls_file>-file-path
iv_filename = <ls_file>-file-filename
iv_data = <ls_file>-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 = <ls_file>-file-path
io_stage->add( iv_path = <ls_file>-file-path
iv_filename = <ls_file>-file-filename
iv_data = <ls_file>-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 }",| ). " Unique page id
ro_html->add( ' formAction: "stage_commit",' ).
ro_html->add( ' ids: {' ).

View File

@ -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.
@ -364,19 +370,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 +394,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 +466,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 +594,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 +659,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
@ -909,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 ).
@ -921,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.
@ -1156,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.
@ -1223,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.
@ -1238,8 +1293,8 @@ CLASS lcl_persistence_migrate IMPLEMENTATION.
lt_users = lcl_user=>list( ).
LOOP AT lt_users ASSIGNING <ls_user>.
lo_user = lcl_app=>user( <ls_user>-user ).
lo_user->set_username( <ls_user>-username ).
lo_user->set_email( <ls_user>-email ).
lo_user->set_default_git_user_name( <ls_user>-username ).
lo_user->set_default_git_user_email( <ls_user>-email ).
ENDLOOP.
ENDMETHOD.

View File

@ -390,7 +390,13 @@ CLASS lcl_popups IMPLEMENTATION.
ELSE.
REPLACE FIRST OCCURRENCE OF lv_head_suffix IN <ls_sel>-varoption WITH ''.
READ TABLE lt_branches WITH KEY display_name = <ls_sel>-varoption ASSIGNING <ls_branch>.
ASSERT sy-subrc = 0.
IF sy-subrc <> 0.
* branch name longer than 65 characters
LOOP AT lt_branches ASSIGNING <ls_branch> WHERE display_name CS <ls_sel>-varoption.
EXIT. " current loop
ENDLOOP.
ENDIF.
ASSERT <ls_branch> IS ASSIGNED.
rs_branch = lo_branches->find_by_name( <ls_branch>-name ).
ENDIF.

View File

@ -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

View File

@ -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 <ls_tadir>.
APPEND INITIAL LINE TO rt_repo_items ASSIGNING <ls_repo_item>.

View File

@ -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: <ls_stage> LIKE LINE OF lt_stage.
lo_dot_abapgit = get_dot_abapgit( ).
lt_stage = io_stage->get_all( ).
LOOP AT lt_stage ASSIGNING <ls_stage> WHERE method = lcl_stage=>c_method-ignore.
mo_dot_abapgit->add_ignore(
lo_dot_abapgit->add_ignore(
iv_path = <ls_stage>-file-path
iv_filename = <ls_stage>-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: <ls_remote> 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( <ls_remote>-data ).
ro_dot = lcl_dot_abapgit=>deserialize( <ls_remote>-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 <ls_return>.
<ls_return>-file-path = gc_root_dir.
<ls_return>-file-filename = gc_dot_abapgit.
<ls_return>-file-data = mo_dot_abapgit->serialize( ).
<ls_return>-file-data = get_dot_abapgit( )->serialize( ).
<ls_return>-file-sha1 = lcl_hash=>sha1( iv_type = gc_type-blob
iv_data = <ls_return>-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 ).

View File

@ -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

View File

@ -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
@ -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.
@ -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.

View File

@ -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.

View File

@ -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( )

View File

@ -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,11 +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_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
@ -1067,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.
@ -1075,7 +1079,8 @@ CLASS lcl_log IMPLEMENTATION.
METHOD to_html.
DATA: lv_string TYPE string.
DATA: lv_class TYPE string,
lv_icon TYPE string.
FIELD-SYMBOLS: <ls_log> LIKE LINE OF mt_log.
@ -1086,11 +1091,21 @@ CLASS lcl_log IMPLEMENTATION.
ENDIF.
LOOP AT mt_log ASSIGNING <ls_log>.
CONCATENATE <ls_log>-msgv1 <ls_log>-msgv2 <ls_log>-msgv3 <ls_log>-msgv4
INTO lv_string SEPARATED BY space.
ro_html->add( '<span class="error">' ).
ro_html->add_icon( iv_name = 'alert' iv_class = 'error' ). " warning CSS exists too
ro_html->add( lv_string ).
CASE <ls_log>-type.
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.
ro_html->add( |<span class="{ lv_class }">| ).
ro_html->add_icon( iv_name = lv_icon ).
ro_html->add( <ls_log>-msg ).
ro_html->add( '</span>' ).
ENDLOOP.
@ -1101,26 +1116,35 @@ CLASS lcl_log IMPLEMENTATION.
FIELD-SYMBOLS: <ls_log> LIKE LINE OF mt_log.
APPEND INITIAL LINE TO mt_log ASSIGNING <ls_log>.
<ls_log>-msgty = 'W'.
<ls_log>-msgid = '00'.
<ls_log>-msgno = '001'.
<ls_log>-msgv1 = iv_msgv1.
<ls_log>-msgv2 = iv_msgv2.
<ls_log>-msgv3 = iv_msgv3.
<ls_log>-msgv4 = iv_msgv4.
<ls_log>-alsort = iv_rc. " Error code for unit test, not sure about better field
<ls_log>-msg = iv_msg.
<ls_log>-type = iv_type.
<ls_log>-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.
@ -1132,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

View File

@ -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 <ls_item>-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( '<div class="repo_container">' ).
ro_html->add( render_grid_menu( ) ).
" Repo content table
ro_html->add( '<table class="repo_tab">' ).
@ -203,59 +207,67 @@ CLASS lcl_gui_view_repo_content IMPLEMENTATION.
ro_html->add( '</div>' ).
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( '<div class="paddings">' ).
ro_html->add( '<table class="w100"><tr>' ).
IF mv_show_folders = abap_true.
ro_html->add( |<td class="current_dir">{ mv_cur_dir }</td>| ).
ENDIF.
ro_html->add( '<td class="right">' ).
ro_html->add( lo_toolbar->render( iv_right = abap_true ) ).
ro_html->add( '</td>' ).
ro_html->add( '</tr></table>' ).
ro_html->add( '</div>' ).
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( iv_as_angle = 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.
@ -313,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.
@ -331,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( '<div class="paddings">' ).
ro_html->add( '<table class="w100"><tr>' ).
IF mv_show_folders = abap_true.
ro_html->add( |<td class="current_dir">{ mv_cur_dir }</td>| ).
ENDIF.
ro_html->add( '<td class="right">' ).
ro_html->add( lo_toolbar->render( ) ).
ro_html->add( '</td>' ).
ro_html->add( '</tr></table>' ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_head_menu
ENDMETHOD. "build_head_menu
METHOD get_item_class.

View File

@ -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.

View File

@ -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