Merge pull request #356 from sbcgua/master

stage_page.js + debug info page #353
This commit is contained in:
Lars Hvam 2016-09-24 08:11:09 +02:00 committed by GitHub
commit 39b83b0f2e
11 changed files with 445 additions and 155 deletions

View File

@ -178,5 +178,6 @@ CONSTANTS: BEGIN OF gc_action,
go_commit TYPE string VALUE 'go_commit',
go_branch_overview TYPE string VALUE 'go_branch_overview',
go_playground TYPE string VALUE 'go_playground',
go_debuginfo TYPE string VALUE 'go_debuginfo',
jump TYPE string VALUE 'jump',
END OF gc_action.

View File

@ -14,4 +14,5 @@ INCLUDE zabapgit_page_db.
INCLUDE zabapgit_page_diff.
INCLUDE zabapgit_page_explore.
INCLUDE zabapgit_page_main.
INCLUDE zabapgit_page_stage.
INCLUDE zabapgit_page_stage.
INCLUDE zabapgit_page_debug.

View File

@ -76,7 +76,8 @@ CLASS lcl_gui_router IMPLEMENTATION.
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
OR gc_action-go_background_run. " Go background run page
OR gc_action-go_background_run " Go background run page
OR gc_action-go_debuginfo. " Go debug info page
ei_page = get_page_by_name( iv_action ).
ev_state = gc_event_state-new_page.
WHEN gc_action-go_background. " Go Background page

View File

@ -16,6 +16,7 @@ CLASS lcl_html_helper DEFINITION FINAL.
DATA mv_html TYPE string READ-ONLY.
DATA mv_indent TYPE i READ-ONLY.
DATA mv_within_style TYPE i READ-ONLY.
DATA mv_within_js TYPE i READ-ONLY.
METHODS add IMPORTING iv_chunk TYPE any.
METHODS reset.
@ -24,7 +25,9 @@ CLASS lcl_html_helper DEFINITION FINAL.
iv_act TYPE string
iv_opt TYPE clike OPTIONAL
iv_typ TYPE char1 DEFAULT gc_action_type-sapevent
iv_class TYPE string OPTIONAL.
iv_class TYPE string OPTIONAL
iv_id TYPE string OPTIONAL
iv_style TYPE string OPTIONAL.
PRIVATE SECTION.
METHODS _add_str IMPORTING iv_str TYPE csequence.
@ -79,6 +82,8 @@ CLASS lcl_html_helper IMPLEMENTATION.
DATA lv_shift_back TYPE i.
DATA lv_style_tag_open TYPE i.
DATA lv_style_tag_close TYPE i.
DATA lv_js_tag_open TYPE i.
DATA lv_js_tag_close TYPE i.
DATA lv_curly TYPE i.
FIND FIRST OCCURRENCE OF '</' IN iv_str MATCH OFFSET lv_close_offs.
@ -87,7 +92,8 @@ CLASS lcl_html_helper IMPLEMENTATION.
ENDIF.
FIND FIRST OCCURRENCE OF '}' IN iv_str MATCH OFFSET lv_close_offs. " Find close } @beginning
IF mv_within_style > 0 AND sy-subrc = 0 AND lv_close_offs = 0 AND mv_indent > 0.
IF ( mv_within_style > 0 OR mv_within_js > 0 )
AND sy-subrc = 0 AND lv_close_offs = 0 AND mv_indent > 0.
lv_shift_back = 1.
ENDIF.
@ -102,11 +108,15 @@ CLASS lcl_html_helper IMPLEMENTATION.
lv_tags_open = lv_tags - lv_tags_close - lv_tags_single.
FIND ALL OCCURRENCES OF '<style' IN iv_str MATCH COUNT lv_style_tag_open IGNORING CASE.
FIND ALL OCCURRENCES OF '<style' IN iv_str MATCH COUNT lv_style_tag_open IGNORING CASE.
FIND ALL OCCURRENCES OF '</style>' IN iv_str MATCH COUNT lv_style_tag_close IGNORING CASE.
mv_within_style = mv_within_style + lv_style_tag_open - lv_style_tag_close.
IF mv_within_style > 0.
FIND ALL OCCURRENCES OF '<script' IN iv_str MATCH COUNT lv_js_tag_open IGNORING CASE.
FIND ALL OCCURRENCES OF '</script>' IN iv_str MATCH COUNT lv_js_tag_close IGNORING CASE.
mv_within_js = mv_within_js + lv_js_tag_open - lv_js_tag_close.
IF mv_within_style > 0 OR mv_within_js > 0.
FIND ALL OCCURRENCES OF '{' IN iv_str MATCH COUNT lv_curly.
lv_tags_open = lv_tags_open + lv_curly.
FIND ALL OCCURRENCES OF '}' IN iv_str MATCH COUNT lv_curly.
@ -137,7 +147,9 @@ CLASS lcl_html_helper IMPLEMENTATION.
METHOD add_anchor.
DATA: lv_class TYPE string,
lv_href TYPE string.
lv_href TYPE string,
lv_id TYPE string,
lv_style TYPE string.
lv_class = iv_class.
@ -166,7 +178,15 @@ CLASS lcl_html_helper IMPLEMENTATION.
ENDCASE.
ENDIF.
_add_str( |<a{ lv_class }{ lv_href }>{ iv_txt }</a>| ).
IF iv_id IS NOT INITIAL.
lv_id = | id="{ iv_id }"|.
ENDIF.
IF iv_style IS NOT INITIAL.
lv_style = | style="{ iv_style }"|.
ENDIF.
_add_str( |<a{ lv_id }{ lv_class }{ lv_href }{ lv_style }>{ iv_txt }</a>| ).
ENDMETHOD. "add_action

View File

@ -206,10 +206,41 @@ CLASS lcl_gui_page_super IMPLEMENTATION.
ro_html->add( '<div id="footer">' ). "#EC NOTEXT
ro_html->add( '<img src="img/logo" >' ). "#EC NOTEXT
ro_html->add( |<span class="version">{ gc_abap_version }</span>| ). "#EC NOTEXT
ro_html->add( '<table width="100%"><tr><td width="40%"></td><td>' ). "#EC NOTEXT
ro_html->add( |<span class="version">{ gc_abap_version }</span>| ). "#EC NOTEXT
ro_html->add( '</td><td id="stdout" width="40%"></td></tr></table>' ). "#EC NOTEXT
ro_html->add( '</div>' ). "#EC NOTEXT
ro_html->add( '</body>' ). "#EC NOTEXT
" Common JS routines
_add '<script type="text/javascript">' . "#EC NOTEXT
_add 'function debugOutput(text, dstID) {'. "#EC NOTEXT
_add ' var stdout = document.getElementById(dstID || "stdout");'. "#EC NOTEXT
_add ' if (stdout.innerHTML == "") {'. "#EC NOTEXT
_add ' stdout.innerHTML = text;'. "#EC NOTEXT
_add ' } else {'. "#EC NOTEXT
_add ' stdout.innerHTML = stdout.innerHTML + "<br>" + text;'. "#EC NOTEXT
_add ' }'. "#EC NOTEXT
_add '}'. "#EC NOTEXT
_add 'function submitForm(params, action) {'. "#EC NOTEXT
_add ' var form = document.createElement("form"); '. "#EC NOTEXT
_add ' form.setAttribute("method", "post"); '. "#EC NOTEXT
_add ' form.setAttribute("action", "sapevent:" + action); '. "#EC NOTEXT
_add ' for(var key in params) {'. "#EC NOTEXT
_add ' var hiddenField = document.createElement("input"); '. "#EC NOTEXT
_add ' hiddenField.setAttribute("type", "hidden"); '. "#EC NOTEXT
_add ' hiddenField.setAttribute("name", key); '. "#EC NOTEXT
_add ' hiddenField.setAttribute("value", params[key]); '. "#EC NOTEXT
_add ' form.appendChild(hiddenField); '. "#EC NOTEXT
_add ' }'. "#EC NOTEXT
_add ' document.body.appendChild(form); '. "#EC NOTEXT
_add ' form.submit(); '. "#EC NOTEXT
_add '}'. "#EC NOTEXT
_add '</script>'. "#EC NOTEXT
IF io_include_script IS BOUND.
ro_html->add( '<script type="text/javascript">' ).
ro_html->add( io_include_script ).
@ -430,6 +461,13 @@ CLASS lcl_gui_page_super IMPLEMENTATION.
_add ' margin: 0;'.
_add ' overflow: hidden;'.
_add '}'.
_add '#stdout {'.
_add ' text-align: right;'.
_add ' padding-right: 0.5em;'.
_add ' color: #ccc;'.
_add ' font-style: italic;'.
_add ' font-size: small;'.
_add '}'.
_add '</style>'.

View File

@ -0,0 +1,80 @@
*&---------------------------------------------------------------------*
*& Include ZABAPGIT_PAGE_DEBUG
*&---------------------------------------------------------------------*
CLASS lcl_gui_page_debuginfo DEFINITION FINAL INHERITING FROM lcl_gui_page_super.
PUBLIC SECTION.
METHODS lif_gui_page~render REDEFINITION.
METHODS styles
RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper.
METHODS scripts
RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper.
PRIVATE SECTION.
METHODS render_debug_info
RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper.
ENDCLASS. "lcl_gui_page_debuginfo
CLASS lcl_gui_page_debuginfo IMPLEMENTATION.
METHOD lif_gui_page~render.
CREATE OBJECT ro_html.
ro_html->add( header( io_include_style = styles( ) ) ).
ro_html->add( title( 'DEBUG INFO' ) ).
ro_html->add( render_debug_info( ) ).
ro_html->add( footer( io_include_script = scripts( ) ) ).
ENDMETHOD.
METHOD render_debug_info.
DATA: lt_ver_tab TYPE filetable,
lv_rc TYPE i,
lv_gui_version TYPE string,
ls_version LIKE LINE OF lt_ver_tab.
cl_gui_frontend_services=>get_gui_version(
CHANGING version_table = lt_ver_tab rc = lv_rc
EXCEPTIONS OTHERS = 1 ).
READ TABLE lt_ver_tab INTO ls_version INDEX 1.
lv_gui_version = ls_version-filename.
READ TABLE lt_ver_tab INTO ls_version INDEX 2.
lv_gui_version = |{ lv_gui_version }.{ ls_version-filename }|.
CREATE OBJECT ro_html.
ro_html->add( '<div id="debug_info" class="debug_container">' ).
ro_html->add( |abapGit version: { gc_abap_version }<br>| ).
ro_html->add( |XML version: { gc_xml_version }<br>| ).
ro_html->add( |GUI version: { lv_gui_version }| ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_debug_info
METHOD styles.
CREATE OBJECT ro_html.
_add '/* DEBUG INFO STYLES */'.
_add 'div.debug_container {'.
_add ' padding: 0.5em;'.
_add ' font-size: 10pt;'.
_add ' color: #444;'.
_add ' font-family: Consolas, Courier, monospace;'.
_add '}'.
ENDMETHOD.
METHOD scripts.
CREATE OBJECT ro_html.
ro_html->add( 'debugOutput("Browser: " + navigator.userAgent, "debug_info");' ).
ENDMETHOD. "scripts
ENDCLASS. "lcl_gui_page_debuginfo

View File

@ -0,0 +1,48 @@
<?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_PAGE_DEBUG</NAME>
<STATE>A</STATE>
<SQLX/>
<EDTX/>
<VARCL>X</VARCL>
<DBAPL/>
<DBNA/>
<CLAS/>
<TYPE/>
<OCCURS/>
<SUBC>I</SUBC>
<APPL/>
<SECU/>
<CNAM/>
<CDAT>0000-00-00</CDAT>
<UNAM/>
<UDAT>0000-00-00</UDAT>
<VERN/>
<LEVL/>
<RSTAT/>
<RMAND/>
<RLOAD>E</RLOAD>
<FIXPT/>
<SSET/>
<SDATE>0000-00-00</SDATE>
<STIME/>
<IDATE>0000-00-00</IDATE>
<ITIME/>
<LDBNAME/>
<UCCHECK>X</UCCHECK>
</PROGDIR>
<TPOOL>
<item>
<ID>R</ID>
<KEY/>
<ENTRY>Include ZABAPGIT_PAGE_DEBUG</ENTRY>
<LENGTH>27</LENGTH>
<SPLIT/>
</item>
</TPOOL>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -145,6 +145,7 @@ CLASS lcl_gui_page_main IMPLEMENTATION.
lo_betasub->add( iv_txt = 'Package to zip' iv_act = gc_action-zip_package ) ##NO_TEXT.
lo_betasub->add( iv_txt = 'Transport to zip' iv_act = gc_action-zip_transport ) ##NO_TEXT.
lo_betasub->add( iv_txt = 'Page playground' iv_act = gc_action-go_playground ) ##NO_TEXT.
lo_betasub->add( iv_txt = 'Debug info' iv_act = gc_action-go_debuginfo ) ##NO_TEXT.
ro_menu->add( iv_txt = 'Clone' iv_act = gc_action-repo_clone ) ##NO_TEXT.
ro_menu->add( iv_txt = 'Explore' iv_act = gc_action-go_explore ) ##NO_TEXT.
@ -675,9 +676,9 @@ CLASS lcl_gui_page_main IMPLEMENTATION.
METHOD lif_gui_page~render.
DATA: lt_repos TYPE lcl_repo_srv=>ty_repo_tt,
lx_error TYPE REF TO lcx_exception,
lo_repo LIKE LINE OF lt_repos.
DATA: lt_repos TYPE lcl_repo_srv=>ty_repo_tt,
lx_error TYPE REF TO lcx_exception,
lo_repo LIKE LINE OF lt_repos.
retrieve_active_repo( ). " Get and validate key of user default repo
mv_hide_files = lcl_app=>user( )->get_hide_files( ).

View File

@ -5,6 +5,11 @@
CLASS lcl_gui_page_stage DEFINITION FINAL INHERITING FROM lcl_gui_page_super.
PUBLIC SECTION.
CONSTANTS: BEGIN OF c_action,
stage_all TYPE string VALUE 'stage_all',
stage_commit TYPE string VALUE 'stage_commit',
END OF c_action.
METHODS:
constructor
IMPORTING io_repo TYPE REF TO lcl_repo_online
@ -20,14 +25,19 @@ CLASS lcl_gui_page_stage DEFINITION FINAL INHERITING FROM lcl_gui_page_super.
METHODS:
render_list
RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper,
render_file
IMPORTING is_file TYPE ty_file
iv_context TYPE string
RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper,
render_menu
RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper,
styles
RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper,
scripts
RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper.
METHODS stage_handle_action
IMPORTING iv_getdata TYPE clike
iv_action TYPE clike
METHODS process_stage_list
IMPORTING it_postdata TYPE cnht_post_data_tab
RAISING lcx_exception.
ENDCLASS.
@ -48,158 +58,152 @@ CLASS lcl_gui_page_stage IMPLEMENTATION.
ENDMETHOD.
METHOD stage_handle_action.
DATA: ls_file TYPE ty_file.
METHOD lif_gui_page~on_event.
FIELD-SYMBOLS: <ls_file> LIKE LINE OF ms_files-local.
IF iv_action <> 'stage_all'.
lcl_html_action_utils=>file_obj_decode( EXPORTING iv_string = iv_getdata
IMPORTING eg_file = ls_file ).
ENDIF.
mo_stage->reset_all( ).
CASE iv_action.
WHEN 'stage_add'.
READ TABLE ms_files-local ASSIGNING <ls_file>
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
iv_filename = <ls_file>-file-filename
iv_data = <ls_file>-file-data ).
WHEN 'stage_all'.
WHEN c_action-stage_all.
LOOP AT ms_files-local ASSIGNING <ls_file>.
mo_stage->add( iv_path = <ls_file>-file-path
iv_filename = <ls_file>-file-filename
iv_data = <ls_file>-file-data ).
ENDLOOP.
WHEN 'stage_reset'.
mo_stage->reset( iv_path = ls_file-path
iv_filename = ls_file-filename ).
WHEN 'stage_ignore'.
mo_stage->ignore( iv_path = ls_file-path
iv_filename = ls_file-filename ).
WHEN 'stage_rm'.
mo_stage->rm( iv_path = ls_file-path
iv_filename = ls_file-filename ).
WHEN c_action-stage_commit.
process_stage_list( it_postdata ).
WHEN OTHERS.
RETURN.
ENDCASE.
ENDMETHOD. "stage_handle_action
CREATE OBJECT ei_page TYPE lcl_gui_page_commit
EXPORTING
io_repo = mo_repo
io_stage = mo_stage.
ev_state = gc_event_state-new_page.
ENDMETHOD.
METHOD process_stage_list.
DATA: lv_string TYPE string,
lt_fields TYPE tihttpnvp,
ls_file TYPE ty_file.
FIELD-SYMBOLS: <ls_file> LIKE LINE OF ms_files-local,
<ls_item> LIKE LINE OF lt_fields.
CONCATENATE LINES OF it_postdata INTO lv_string.
lt_fields = cl_http_utility=>if_http_utility~string_to_fields( |{ lv_string }| ).
IF lines( lt_fields ) = 0.
lcx_exception=>raise( 'process_stage_list: empty list' ).
ENDIF.
LOOP AT lt_fields ASSIGNING <ls_item>.
lcl_url=>split_file_location( EXPORTING iv_fullpath = <ls_item>-name
IMPORTING ev_path = ls_file-path
ev_filename = ls_file-filename ).
CASE <ls_item>-value.
WHEN lcl_stage=>c_method-add.
READ TABLE ms_files-local ASSIGNING <ls_file>
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
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
iv_filename = ls_file-filename ).
WHEN lcl_stage=>c_method-rm.
mo_stage->rm( iv_path = ls_file-path
iv_filename = ls_file-filename ).
WHEN lcl_stage=>c_method-skip.
" Do nothing
WHEN OTHERS.
lcx_exception=>raise( |process_stage_list: unknown method { <ls_item>-value }| ).
ENDCASE.
ENDLOOP.
ENDMETHOD. "process_stage_list
METHOD render_list.
DATA: lv_method TYPE lcl_stage=>ty_method,
lv_param TYPE string,
lv_status TYPE string,
lo_toolbar TYPE REF TO lcl_html_toolbar.
FIELD-SYMBOLS: <ls_remote> LIKE LINE OF ms_files-remote,
<ls_local> LIKE LINE OF ms_files-local.
CREATE OBJECT ro_html.
ro_html->add( '<table class="stage_tab">' ).
ro_html->add( '<table id="stage_tab" class="stage_tab">' ).
" Local changes
LOOP AT ms_files-local ASSIGNING <ls_local>.
IF sy-tabix = 1.
ro_html->add('<tr class="separator firstrow">').
ro_html->add( '<td></td><td colspan="2">LOCAL</td>' ).
ro_html->add('</tr>').
ENDIF.
AT FIRST.
ro_html->add('<thead><tr>').
ro_html->add('<th></th><th colspan="3">LOCAL</th>' ).
ro_html->add('</tr></thead>').
ro_html->add('<tbody class="local">').
ENDAT.
lv_method = mo_stage->lookup( iv_path = <ls_local>-file-path
iv_filename = <ls_local>-file-filename ).
lv_param = lcl_html_action_utils=>file_encode( iv_key = mo_repo->get_key( )
ig_file = <ls_local>-file ).
ro_html->add( render_file( is_file = <ls_local>-file iv_context = 'local' ) ).
CREATE OBJECT lo_toolbar.
IF lv_method IS NOT INITIAL.
lo_toolbar->add( iv_txt = 'reset'
iv_act = 'stage_reset?' && lv_param ) ##NO_TEXT.
ELSE.
lo_toolbar->add( iv_txt = 'add'
iv_act = 'stage_add?' && lv_param ) ##NO_TEXT.
ENDIF.
lo_toolbar->add( iv_txt = 'diff'
iv_act = |{ gc_action-go_diff }?{ lv_param }| ) ##NO_TEXT.
IF lv_method IS INITIAL.
lv_status = '<span class="grey">?</span>'.
ELSE.
lv_status = lv_method.
ENDIF.
ro_html->add( '<tr>' ).
ro_html->add( |<td class="status">{ lv_status }</td>| ).
ro_html->add( |<td>{ <ls_local>-file-path && <ls_local>-file-filename }</td>| ).
ro_html->add( '<td>' ).
ro_html->add( lo_toolbar->render( iv_no_separator = abap_true ) ).
ro_html->add( '</td>' ).
ro_html->add( '</tr>' ).
AT LAST.
ro_html->add('</tbody>').
ENDAT.
ENDLOOP.
" Remote changes
LOOP AT ms_files-remote ASSIGNING <ls_remote>.
IF sy-tabix = 1.
ro_html->add('<tr class="separator">').
ro_html->add( '<td></td><td colspan="2">REMOTE</td>' ).
ro_html->add('</tr>').
ENDIF.
AT FIRST.
ro_html->add('<thead><tr>').
ro_html->add('<th></th><th colspan="3">REMOTE</th>' ).
ro_html->add('</tr></thead>').
ro_html->add('<tbody class="remote">').
ENDAT.
lv_method = mo_stage->lookup( iv_path = <ls_remote>-path
iv_filename = <ls_remote>-filename ).
lv_param = lcl_html_action_utils=>file_encode( iv_key = mo_repo->get_key( )
ig_file = <ls_remote> ).
ro_html->add( render_file( is_file = <ls_remote> iv_context = 'remote' ) ).
CREATE OBJECT lo_toolbar.
IF lv_method IS NOT INITIAL.
lo_toolbar->add( iv_txt = 'reset' iv_act = 'stage_reset?' && lv_param ) ##NO_TEXT.
ELSE.
lo_toolbar->add( iv_txt = 'ignore' iv_act = 'stage_ignore?' && lv_param ) ##NO_TEXT.
lo_toolbar->add( iv_txt = 'remove' iv_act = 'stage_rm?' && lv_param ) ##NO_TEXT.
ENDIF.
IF lv_method IS INITIAL.
lv_status = '<span class="grey">?</span>'.
ELSE.
lv_status = lv_method.
ENDIF.
ro_html->add( '<tr>' ).
ro_html->add( |<td class="status">{ lv_status }</td>| ).
ro_html->add( |<td>{ <ls_remote>-path && <ls_remote>-filename }</td>| ).
ro_html->add( '<td>' ).
ro_html->add( lo_toolbar->render( iv_no_separator = abap_true ) ).
ro_html->add( '</td>' ).
ro_html->add( '</tr>' ).
AT LAST.
ro_html->add('</tbody>').
ENDAT.
ENDLOOP.
ro_html->add( '</table>' ).
ENDMETHOD. "render_lines
METHOD lif_gui_page~on_event.
METHOD render_file.
CASE iv_action.
WHEN 'stage_all'
OR 'stage_commit'.
IF iv_action = 'stage_all'.
stage_handle_action( iv_getdata = iv_getdata iv_action = iv_action ).
ENDIF.
CREATE OBJECT ei_page TYPE lcl_gui_page_commit
EXPORTING
io_repo = mo_repo
io_stage = mo_stage.
ev_state = gc_event_state-new_page.
WHEN 'stage_add'
OR 'stage_reset'
OR 'stage_ignore'
OR 'stage_rm'.
stage_handle_action( iv_getdata = iv_getdata iv_action = iv_action ).
ev_state = gc_event_state-re_render.
DATA lv_param TYPE string.
CREATE OBJECT ro_html.
ro_html->add( |<tr class="{ iv_context }">| ).
ro_html->add( |<td class="status" style="color: #CCC">?</td>| ).
ro_html->add( |<td>{ is_file-path && is_file-filename }</td>| ).
CASE iv_context.
WHEN 'local'.
lv_param = lcl_html_action_utils=>file_encode( iv_key = mo_repo->get_key( )
ig_file = is_file ).
ro_html->add( '<td class="cmd"><a>add</a></td>' ).
ro_html->add( '<td>' ).
ro_html->add_anchor( iv_txt = 'diff' iv_act = |{ gc_action-go_diff }?{ lv_param }| ).
ro_html->add( '</td>' ).
WHEN 'remote'.
ro_html->add( '<td class="cmd"><a>ignore</a><a>remove</a></td>' ).
ro_html->add( |<td><span class="grey">-</span></td>| ).
ENDCASE.
ENDMETHOD.
ro_html->add( '</tr>' ).
ENDMETHOD. "render_file
METHOD lif_gui_page~render.
@ -211,36 +215,27 @@ CLASS lcl_gui_page_stage IMPLEMENTATION.
ro_html->add( '<div class="repo">' ).
ro_html->add( render_repo_top( mo_repo ) ).
ro_html->add( render_menu( ) ).
ro_html->add( render_list( ) ).
ro_html->add( '</div>' ).
ro_html->add( footer( ) ).
ro_html->add( footer( scripts( ) ) ).
ENDMETHOD. "lif_gui_page~render
METHOD render_menu.
DATA: lo_toolbar TYPE REF TO lcl_html_toolbar,
lv_action TYPE string.
CREATE OBJECT ro_html.
CREATE OBJECT lo_toolbar.
lv_action = lcl_html_action_utils=>repo_key_encode( mo_repo->get_key( ) ).
IF mo_stage->count( ) > 0.
lo_toolbar->add( iv_act = |stage_commit?{ lv_action }|
iv_txt = 'Commit'
iv_opt = gc_html_opt-emphas ) ##NO_TEXT.
ELSEIF lines( ms_files-local ) > 0.
lo_toolbar->add( iv_act = |stage_all?{ lv_action }|
iv_txt = 'Add all and commit') ##NO_TEXT.
ENDIF.
ro_html->add( '<div class="paddings">' ).
ro_html->add( lo_toolbar->render( ) ).
ro_html->add_anchor( iv_act = 'commit();'
iv_typ = gc_action_type-onclick
iv_id = 'act_commit'
iv_style = 'display: none'
iv_txt = 'Commit'
iv_opt = gc_html_opt-emphas ) ##NO_TEXT.
ro_html->add_anchor( iv_act = |{ c_action-stage_all }|
iv_id = 'act_commit_all'
iv_txt = 'Add all and commit') ##NO_TEXT.
ro_html->add( '</div>' ).
ENDMETHOD. "render_menu
@ -261,18 +256,90 @@ CLASS lcl_gui_page_stage IMPLEMENTATION.
_add ' vertical-align: middle;'.
_add ' padding: 2px 0.5em;'.
_add '}'.
_add '.stage_tab th {'.
_add ' color: #BBB;'.
_add ' font-size: 10pt;'.
_add ' text-align: left;'.
_add ' font-weight: normal;'.
_add ' background-color: #edf2f9;'.
_add ' padding: 4px 0.5em;'.
_add '}'.
_add '.stage_tab td.status {'.
_add ' width: 2em;'.
_add ' text-align: center;'.
_add '}'.
_add '.stage_tab tr.separator td {'.
_add ' color: #BBB;'.
_add ' font-size: 10pt;'.
_add ' background-color: #edf2f9;'.
_add ' padding: 4px 0.5em;'.
_add '}'.
_add '.stage_tab tr.firstrow td { border-top: 0px; } '.
_add '.stage_tab tbody tr:first-child td { padding-top: 0.5em; }'.
_add '.stage_tab tbody tr:last-child td { padding-bottom: 0.5em; }'.
_add '.stage_tab td.cmd a { padding: 0px 4px; }'.
ENDMETHOD. "styles
METHOD scripts.
CREATE OBJECT ro_html.
" Hook global click listener on table, global action counter
_add 'document.getElementById("stage_tab").addEventListener("click", onEvent);'.
_add 'var gChoiceCount = 0;'.
" Event handler, change status
_add 'function onEvent(event) {'.
_add ' if (event.target.tagName != "A") return;'.
_add ' var td = event.target.parentNode;'.
_add ' if (!td || td.tagName != "TD" || td.className != "cmd") return;'.
_add ' var cmd = event.target.innerText;'.
_add ' var tr = td.parentNode;'.
_add ' var context = tr.parentNode.className;'.
_add ' switch (cmd) {'.
_add ' case "add": cmd = "A"; gChoiceCount++; break;'.
_add ' case "remove": cmd = "R"; gChoiceCount++; break;'.
_add ' case "ignore": cmd = "I"; gChoiceCount++; break;'.
_add ' case "reset": cmd = "?"; gChoiceCount--; break;'.
_add ' }'.
_add ' formatTR(tr, cmd, context);'.
_add ' updateMenu();'.
_add '}'.
" Re-format table line
_add 'function formatTR(tr, cmd, context) {'.
_add ' const cmdReset = "<a>reset</a>"; '.
_add ' const cmdLocal = "<a>add</a>"; '.
_add ' const cmdRemote = "<a>ignore</a><a>remove</a>";'.
_add ' tr.cells[0].innerText = cmd;'.
_add ' tr.cells[0].style.color = (cmd == "?")?"#CCC":"";'.
_add ' tr.cells[2].innerHTML = (cmd != "?")?cmdReset'.
_add ' :(context == "local")?cmdLocal:cmdRemote;'.
_add '}'.
" Update menu items visibility
_add 'function updateMenu() {'.
_add ' if (gChoiceCount > 0) {'.
_add ' document.getElementById("act_commit").style.display = "inline";'.
_add ' document.getElementById("act_commit_all").style.display = "none";'.
_add ' } else {'.
_add ' document.getElementById("act_commit").style.display = "none";'.
_add ' document.getElementById("act_commit_all").style.display = "inline";'.
_add ' }'.
_add '}'.
" Commit change to the server
_add 'function commit() {'.
_add ' var data = collectData();'.
ro_html->add( | submitForm(data, "{ c_action-stage_commit }");| ).
_add '}'.
" Extract data from the table
_add 'function collectData() {'.
_add ' var stage = document.getElementById("stage_tab");'.
_add ' var data = {};'.
_add ' for (var i = stage.rows.length - 1; i >= 0; i--) {'.
_add ' var row = stage.rows[i];'.
_add ' if (row.parentNode.tagName == "THEAD") continue;'.
_add ' data[row.cells[1].innerText] = row.cells[0].innerText;'.
_add ' }'.
_add ' return data; '.
_add '}'.
ENDMETHOD. "scripts
ENDCLASS.

View File

@ -12,6 +12,7 @@ CLASS lcl_stage DEFINITION FINAL.
add TYPE ty_method VALUE 'A',
rm TYPE ty_method VALUE 'R',
ignore TYPE ty_method VALUE 'I',
skip TYPE ty_method VALUE '?',
END OF c_method.
TYPES: BEGIN OF ty_stage,
@ -45,6 +46,8 @@ CLASS lcl_stage DEFINITION FINAL.
IMPORTING iv_path TYPE ty_file-path
iv_filename TYPE ty_file-filename
RAISING lcx_exception,
reset_all
RAISING lcx_exception,
rm
IMPORTING iv_path TYPE ty_file-path
iv_filename TYPE ty_file-filename
@ -170,6 +173,10 @@ CLASS lcl_stage IMPLEMENTATION.
ASSERT sy-subrc = 0.
ENDMETHOD. "reset
METHOD reset_all.
CLEAR mt_stage.
ENDMETHOD. "reset_all
METHOD rm.
append( iv_path = iv_path
iv_filename = iv_filename

View File

@ -360,6 +360,11 @@ CLASS lcl_url DEFINITION FINAL.
RETURNING VALUE(rv_path_name) TYPE string
RAISING lcx_exception.
CLASS-METHODS split_file_location
IMPORTING iv_fullpath TYPE string
EXPORTING ev_path TYPE string
ev_filename TYPE string.
PRIVATE SECTION.
CLASS-METHODS regex
IMPORTING iv_repo TYPE string
@ -377,6 +382,27 @@ ENDCLASS. "lcl_repo DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_url IMPLEMENTATION.
METHOD split_file_location.
DATA: lv_cnt TYPE i,
lv_off TYPE i,
lv_len TYPE i.
FIND FIRST OCCURRENCE OF REGEX '^/(.*/)?' IN iv_fullpath
MATCH COUNT lv_cnt
MATCH OFFSET lv_off
MATCH LENGTH lv_len.
IF lv_cnt > 0.
ev_path = iv_fullpath+0(lv_len).
ev_filename = iv_fullpath+lv_len.
ELSE.
CLEAR ev_path.
ev_filename = iv_fullpath.
ENDIF.
ENDMETHOD. "split_file_location
METHOD host.
regex( EXPORTING iv_repo = iv_repo
IMPORTING ev_host = rv_host ).