CTS integration (#2061)

* Implement facade for Change Transport System

* Render lock item in VIEW_REPO

* Add jump to SE01

* Display transport on stage page

* Optimize transport read on stage page

* Error handling CTS

* Fix indentation

* Disable transport column for local packages

* Code review changes
This commit is contained in:
Fabian Lupa 2018-11-09 05:36:44 +01:00 committed by Lars Hvam
parent 7cdbbc92b6
commit b08ee6a498
11 changed files with 413 additions and 68 deletions

View File

@ -34,6 +34,12 @@ CLASS zcl_abapgit_gui_page_stage DEFINITION
END OF ty_changed_by .
TYPES:
ty_changed_by_tt TYPE SORTED TABLE OF ty_changed_by WITH UNIQUE KEY item.
TYPES:
BEGIN OF ty_transport,
item TYPE zif_abapgit_definitions=>ty_item,
transport TYPE trkorr,
END OF ty_transport,
ty_transport_tt TYPE SORTED TABLE OF ty_transport WITH UNIQUE KEY item.
DATA mo_repo TYPE REF TO zcl_abapgit_repo_online .
DATA ms_files TYPE zif_abapgit_definitions=>ty_stage_files .
@ -45,6 +51,11 @@ CLASS zcl_abapgit_gui_page_stage DEFINITION
!it_local TYPE zif_abapgit_definitions=>ty_files_item_tt
RETURNING
VALUE(rt_changed_by) TYPE ty_changed_by_tt .
METHODS find_transports
IMPORTING
it_local TYPE zif_abapgit_definitions=>ty_files_item_tt
RETURNING
VALUE(rt_transports) TYPE ty_transport_tt.
METHODS render_list
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
@ -54,6 +65,7 @@ CLASS zcl_abapgit_gui_page_stage DEFINITION
!is_file TYPE zif_abapgit_definitions=>ty_file
!is_item TYPE zif_abapgit_definitions=>ty_item OPTIONAL
!iv_changed_by TYPE xubname OPTIONAL
!iv_transport TYPE trkorr OPTIONAL
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
METHODS render_actions
@ -77,7 +89,7 @@ ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
CLASS zcl_abapgit_gui_page_stage IMPLEMENTATION.
METHOD build_menu.
@ -135,6 +147,43 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
ENDMETHOD.
METHOD find_transports.
DATA: li_cts_api TYPE REF TO zif_abapgit_cts_api,
ls_new LIKE LINE OF rt_transports.
FIELD-SYMBOLS: <ls_local> LIKE LINE OF it_local,
<ls_new> LIKE LINE OF rt_transports.
li_cts_api = zcl_abapgit_factory=>get_cts_api( ).
TRY.
LOOP AT it_local ASSIGNING <ls_local> WHERE item IS NOT INITIAL.
IF <ls_local>-item-obj_type IS NOT INITIAL AND
<ls_local>-item-obj_name IS NOT INITIAL AND
<ls_local>-item-devclass IS NOT INITIAL.
IF li_cts_api->is_chrec_possible_for_package( <ls_local>-item-devclass ) = abap_false.
EXIT. " Assume all other objects are also in packages without change recording
ELSEIF li_cts_api->is_object_type_lockable( <ls_local>-item-obj_type ) = abap_true AND
li_cts_api->is_object_locked_in_transport( iv_object_type = <ls_local>-item-obj_type
iv_object_name = <ls_local>-item-obj_name ) = abap_true.
ls_new-item = <ls_local>-item.
ls_new-transport = li_cts_api->get_current_transport_for_obj(
iv_object_type = <ls_local>-item-obj_type
iv_object_name = <ls_local>-item-obj_name
iv_resolve_task_to_request = abap_false ).
INSERT ls_new INTO TABLE rt_transports.
ENDIF.
ENDIF.
ENDLOOP.
CATCH zcx_abapgit_exception.
ASSERT 1 = 2.
ENDTRY.
ENDMETHOD.
METHOD get_page_patch.
@ -288,11 +337,15 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
METHOD render_file.
DATA: lv_param TYPE string,
lv_filename TYPE string.
DATA: lv_param TYPE string,
lv_filename TYPE string,
lv_transport_string TYPE string,
lv_transport_html TYPE string.
CREATE OBJECT ro_html.
lv_transport_string = iv_transport.
lv_filename = is_file-path && is_file-filename.
* make sure whitespace is preserved in the DOM
REPLACE ALL OCCURRENCES OF ` ` IN lv_filename WITH '&nbsp;'.
@ -308,13 +361,21 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
lv_filename = zcl_abapgit_html=>a(
iv_txt = lv_filename
iv_act = |{ zif_abapgit_definitions=>c_action-go_diff }?{ lv_param }| ).
IF iv_transport IS NOT INITIAL.
lv_transport_html = zcl_abapgit_html=>a(
iv_txt = lv_transport_string
iv_act = |{ zif_abapgit_definitions=>c_action-jump_transport }?{ iv_transport }| ).
ENDIF.
ro_html->add( |<td class="type">{ is_item-obj_type }</td>| ).
ro_html->add( |<td class="name">{ lv_filename }</td>| ).
ro_html->add( |<td class="user">{ iv_changed_by }</td>| ).
ro_html->add( |<td class="transport">{ lv_transport_html }</td>| ).
WHEN 'remote'.
ro_html->add( '<td class="type">-</td>' ). " Dummy for object type
ro_html->add( |<td class="name">{ lv_filename }</td>| ).
ro_html->add( '<td></td>' ). " Dummy for changed-by
ro_html->add( '<td></td>' ). " Dummy for transport
ENDCASE.
ro_html->add( |<td class="status">?</td>| ).
@ -328,7 +389,9 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
METHOD render_list.
DATA: lt_changed_by TYPE ty_changed_by_tt,
ls_changed_by LIKE LINE OF lt_changed_by.
ls_changed_by LIKE LINE OF lt_changed_by,
lt_transports TYPE ty_transport_tt,
ls_transport LIKE LINE OF lt_transports.
FIELD-SYMBOLS: <ls_remote> LIKE LINE OF ms_files-remote,
<ls_local> LIKE LINE OF ms_files-local.
@ -338,6 +401,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
ro_html->add( '<table id="stageTab" class="stage_tab w100">' ).
lt_changed_by = find_changed_by( ms_files-local ).
lt_transports = find_transports( ms_files-local ).
" Local changes
LOOP AT ms_files-local ASSIGNING <ls_local>.
@ -346,6 +410,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
ro_html->add( '<th>Type</th>' ).
ro_html->add( '<th>Files to add (click to see diff)</th>' ).
ro_html->add( '<th>Changed by</th>' ).
ro_html->add( '<th>Transport</th>' ).
ro_html->add( '<th></th>' ). " Status
ro_html->add( '<th class="cmd">' ).
ro_html->add( '<a>add</a>&#x2193; <a>reset</a>&#x2193;' ).
@ -355,12 +420,16 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
ENDAT.
READ TABLE lt_changed_by INTO ls_changed_by WITH KEY item = <ls_local>-item. "#EC CI_SUBRC
READ TABLE lt_transports INTO ls_transport WITH KEY item = <ls_local>-item. "#EC CI_SUBRC
ro_html->add( render_file(
iv_context = 'local'
is_file = <ls_local>-file
is_item = <ls_local>-item
iv_changed_by = ls_changed_by-name ) ).
iv_changed_by = ls_changed_by-name
iv_transport = ls_transport-transport ) ).
CLEAR ls_transport.
AT LAST.
ro_html->add( '</tbody>' ).

View File

@ -40,11 +40,14 @@ CLASS zcl_abapgit_gui_router DEFINITION
METHODS get_page_playground
RETURNING VALUE(ri_page) TYPE REF TO zif_abapgit_gui_page
RAISING zcx_abapgit_exception zcx_abapgit_cancel.
CLASS-METHODS jump_display_transport
IMPORTING iv_getdata TYPE clike.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION.
CLASS zcl_abapgit_gui_router IMPLEMENTATION.
METHOD get_page_background.
@ -241,6 +244,9 @@ CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION.
WHEN zif_abapgit_definitions=>c_action-jump_pkg. " Open SE80
zcl_abapgit_services_repo=>open_se80( |{ iv_getdata }| ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
WHEN zif_abapgit_definitions=>c_action-jump_transport.
jump_display_transport( iv_getdata ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
" DB actions
WHEN zif_abapgit_definitions=>c_action-db_edit.
@ -376,4 +382,14 @@ CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION.
ENDCASE.
ENDMETHOD.
METHOD jump_display_transport.
DATA: lv_transport TYPE trkorr.
lv_transport = iv_getdata.
CALL FUNCTION 'TR_DISPLAY_REQUEST'
EXPORTING
i_trkorr = lv_transport.
ENDMETHOD.
ENDCLASS.

View File

@ -50,8 +50,9 @@ CLASS zcl_abapgit_gui_view_repo DEFINITION
RETURNING VALUE(ro_toolbar) TYPE REF TO zcl_abapgit_html_toolbar
RAISING zcx_abapgit_exception,
render_item
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
iv_render_transports TYPE abap_bool
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception,
render_item_files
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
@ -65,6 +66,9 @@ CLASS zcl_abapgit_gui_view_repo DEFINITION
get_item_icon
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
RETURNING VALUE(rv_html) TYPE string,
render_item_lock_column
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
RETURNING VALUE(rv_html) TYPE string,
render_empty_package
RETURNING VALUE(rv_html) TYPE string,
render_parent_dir
@ -85,7 +89,7 @@ ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_VIEW_REPO IMPLEMENTATION.
CLASS zcl_abapgit_gui_view_repo IMPLEMENTATION.
METHOD build_dir_jump_link.
@ -398,20 +402,29 @@ CLASS ZCL_ABAPGIT_GUI_VIEW_REPO IMPLEMENTATION.
METHOD render_item.
DATA: lv_link TYPE string.
DATA: lv_link TYPE string,
lv_colspan TYPE i.
CREATE OBJECT ro_html.
IF iv_render_transports = abap_false.
lv_colspan = 2.
ELSE.
lv_colspan = 3.
ENDIF.
ro_html->add( |<tr{ get_item_class( is_item ) }>| ).
IF is_item-obj_name IS INITIAL AND is_item-is_dir = abap_false.
ro_html->add( '<td colspan="2"></td>'
ro_html->add( |<td colspan="{ lv_colspan }"></td>|
&& '<td class="object">'
&& '<i class="grey">non-code and meta files</i>'
&& '</td>' ).
ELSE.
ro_html->add( |<td class="icon">{ get_item_icon( is_item ) }</td>| ).
IF iv_render_transports = abap_true.
ro_html->add( render_item_lock_column( is_item ) ).
ENDIF.
IF is_item-is_dir = abap_true. " Subdir
lv_link = build_dir_jump_link( is_item-path ).
@ -528,6 +541,38 @@ CLASS ZCL_ABAPGIT_GUI_VIEW_REPO IMPLEMENTATION.
ENDMETHOD.
METHOD render_item_lock_column.
DATA: li_cts_api TYPE REF TO zif_abapgit_cts_api,
lv_transport TYPE trkorr,
lv_transport_string TYPE string,
lv_icon_html TYPE string.
li_cts_api = zcl_abapgit_factory=>get_cts_api( ).
TRY.
IF is_item-obj_type IS INITIAL OR is_item-obj_name IS INITIAL OR
li_cts_api->is_object_type_lockable( is_item-obj_type ) = abap_false OR
li_cts_api->is_object_locked_in_transport( iv_object_type = is_item-obj_type
iv_object_name = is_item-obj_name ) = abap_false.
rv_html = |<td class="icon"></td>|.
ELSE.
lv_transport = li_cts_api->get_current_transport_for_obj( iv_object_type = is_item-obj_type
iv_object_name = is_item-obj_name
iv_resolve_task_to_request = abap_false ).
lv_transport_string = lv_transport.
lv_icon_html = zcl_abapgit_html=>a( iv_txt = zcl_abapgit_html=>icon( iv_name = 'lock/darkgrey'
iv_hint = lv_transport_string )
iv_act = |{ zif_abapgit_definitions=>c_action-jump_transport }?| &&
lv_transport ).
rv_html = |<td class="icon">| &&
|{ lv_icon_html }| &&
|</td>|.
ENDIF.
CATCH zcx_abapgit_exception.
ASSERT 1 = 2.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
@ -563,15 +608,16 @@ CLASS ZCL_ABAPGIT_GUI_VIEW_REPO IMPLEMENTATION.
METHOD zif_abapgit_gui_page~render.
DATA: lt_repo_items TYPE zif_abapgit_definitions=>tt_repo_items,
lo_browser TYPE REF TO zcl_abapgit_repo_content_list,
lx_error TYPE REF TO zcx_abapgit_exception,
lv_lstate TYPE char1,
lv_rstate TYPE char1,
lv_max TYPE abap_bool,
lv_max_str TYPE string,
lv_add_str TYPE string,
lo_log TYPE REF TO zcl_abapgit_log.
DATA: lt_repo_items TYPE zif_abapgit_definitions=>tt_repo_items,
lo_browser TYPE REF TO zcl_abapgit_repo_content_list,
lx_error TYPE REF TO zcx_abapgit_exception,
lv_lstate TYPE char1,
lv_rstate TYPE char1,
lv_max TYPE abap_bool,
lv_max_str TYPE string,
lv_add_str TYPE string,
lo_log TYPE REF TO zcl_abapgit_log,
lv_render_transports TYPE abap_bool.
FIELD-SYMBOLS <ls_item> LIKE LINE OF lt_repo_items.
@ -582,6 +628,9 @@ CLASS ZCL_ABAPGIT_GUI_VIEW_REPO IMPLEMENTATION.
TRY.
lv_render_transports = zcl_abapgit_factory=>get_cts_api(
)->is_chrec_possible_for_package( mo_repo->get_package( ) ).
CREATE OBJECT lo_browser
EXPORTING
io_repo = mo_repo.
@ -624,7 +673,7 @@ CLASS ZCL_ABAPGIT_GUI_VIEW_REPO IMPLEMENTATION.
lv_max = abap_true.
EXIT. " current loop
ENDIF.
ro_html->add( render_item( <ls_item> ) ).
ro_html->add( render_item( is_item = <ls_item> iv_render_transports = lv_render_transports ) ).
ENDLOOP.
ENDIF.

View File

@ -24,7 +24,7 @@ if (!Function.prototype.bind) {
};
if (this.prototype) {
fNOP.prototype = this.prototype;
fNOP.prototype = this.prototype;
}
fBound.prototype = new fNOP();
@ -39,7 +39,7 @@ if (!String.prototype.includes) {
if (typeof start !== 'number') {
start = 0;
}
if (start + search.length > this.length) {
return false;
} else {
@ -64,7 +64,7 @@ function submitSapeventForm(params, action, method) {
var form = document.createElement("form");
form.setAttribute("method", method || "post");
form.setAttribute("action", "sapevent:" + action);
for(var key in params) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
@ -133,8 +133,8 @@ function perfOut(prefix) {
var keys = Object.keys(totals);
for (var i = keys.length - 1; i >= 0; i--) {
console.log(prefix
+ " " + keys[i] + ": "
console.log(prefix
+ " " + keys[i] + ": "
+ totals[keys[i]].time.toFixed(3) + "ms"
+ " (" + totals[keys[i]].count.toFixed() +")");
}
@ -190,10 +190,10 @@ function StageHelper(params) {
objectSearch: document.getElementById(params.ids.objectSearch),
fileCounter: document.getElementById(params.ids.fileCounter)
};
// Table columns (autodetection)
this.colIndex = this.detectColumns();
this.filterTargets = ["name", "user"];
this.filterTargets = ["name", "user", "transport"];
// Constants
this.HIGHLIGHT_STYLE = "highlight";
@ -204,7 +204,7 @@ function StageHelper(params) {
reset: "?",
isValid: function (status) { return "ARI?".indexOf(status) == -1; }
};
this.TEMPLATES = {
cmdReset: "<a>reset</a>",
cmdLocal: "<a>add</a>",
@ -275,10 +275,10 @@ StageHelper.prototype.onTableClick = function (event) {
} else return;
if (["TD","TH"].indexOf(td.tagName) == -1 || td.className != "cmd") return;
var status = this.STATUS[target.innerText]; // Convert anchor text to status
var targetRow = td.parentNode;
if (td.tagName === "TD") {
this.updateRow(targetRow, status);
} else { // TH
@ -298,7 +298,7 @@ StageHelper.prototype.onTableClick = function (event) {
StageHelper.prototype.onFilter = function (e) {
if ( // Enter hit or clear, IE SUCKS !
e.type === "input" && !e.target.value && this.lastFilterValue
|| e.type === "keypress" && e.which === 13 ) {
|| e.type === "keypress" && e.which === 13 ) {
this.applyFilterValue(e.target.value);
submitSapeventForm({ 'filterValue': e.target.value }, "stage_filter", "post");
@ -325,7 +325,7 @@ StageHelper.prototype.applyFilterToRow = function (row, filter) {
};
}, this);
var isVisible = false;
var isVisible = false;
// Apply filter to cells, mark filtered text
for (var i = targets.length - 1; i >= 0; i--) {
@ -346,8 +346,8 @@ StageHelper.prototype.applyFilterToRow = function (row, filter) {
// Get how status should affect object counter
StageHelper.prototype.getStatusImpact = function (status) {
if (typeof status !== "string"
|| status.length !== 1
if (typeof status !== "string"
|| status.length !== 1
|| this.STATUS.isValid(status) ) {
alert("Unknown status");
} else {
@ -383,8 +383,8 @@ StageHelper.prototype.updateRowStatus = function (row, status) {
StageHelper.prototype.updateRowCommand = function (row, status) {
var cell = row.cells[this.colIndex["cmd"]];
if (status === this.STATUS.reset) {
cell.innerHTML = (row.className == "local")
? this.TEMPLATES.cmdLocal
cell.innerHTML = (row.className == "local")
? this.TEMPLATES.cmdLocal
: this.TEMPLATES.cmdRemote;
} else {
cell.innerHTML = this.TEMPLATES.cmdReset;
@ -413,7 +413,7 @@ StageHelper.prototype.collectData = function () {
}
// Table iteration helper
StageHelper.prototype.iterateStageTab = function (changeMode, cb /*, ...*/) {
StageHelper.prototype.iterateStageTab = function (changeMode, cb /*, ...*/) {
var restArgs = Array.prototype.slice.call(arguments, 2);
var table = this.dom.stageTab;
@ -502,7 +502,7 @@ function DiffHelper(params) {
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) {
@ -581,14 +581,14 @@ function displayNews() {
div.style.display = (div.style.display) ? '' : 'none';
}
// Hotkey Overview
// Hotkey Overview
function closeHotkeyOverview() {
var div = document.getElementById("hotkeys");
div.style.display = (div.style.display) ? '' : 'none';
}
function KeyNavigation() {
}
KeyNavigation.prototype.onkeydown = function(oEvent) {
@ -621,7 +621,7 @@ KeyNavigation.prototype.getActiveElementParent = function () {
};
KeyNavigation.prototype.onEnterOrSpace = function (oEvent) {
// Enter or space clicks the selected link
var liSelected = this.getLiSelected();
@ -695,7 +695,7 @@ function enableArrowListNavigation() {
}
function LinkHints(sLinkHintKey, sColor){
this.sLinkHintKey = sLinkHintKey;
this.sLinkHintKey = sLinkHintKey;
this.sColor = sColor;
this.oTooltipMap = {};
this.bTooltipsOn = false;
@ -715,7 +715,7 @@ LinkHints.prototype.fnRenderTooltip = function (oTooltip, iTooltipCounter) {
};
LinkHints.prototype.getTooltipStartValue = function(iToolTipCount){
// if whe have 333 tooltips we start from 100
return Math.pow(10,iToolTipCount.toString().length - 1);
@ -724,10 +724,10 @@ LinkHints.prototype.getTooltipStartValue = function(iToolTipCount){
LinkHints.prototype.fnRenderTooltips = function () {
// all possible links which should be accessed via tooltip have
// sub span which is hidden by default. If we like to show the
// sub span which is hidden by default. If we like to show the
// tooltip we have to toggle the css class 'hidden'.
//
// We use numeric values for the tooltip label. Maybe we can
//
// We use numeric values for the tooltip label. Maybe we can
// support also alphanumeric chars in the future. Then we have to
// calculate permutations and that's work. So for the sake of simplicity
// we stick to numeric values and just increment them.
@ -784,7 +784,7 @@ LinkHints.prototype.fnFilterTooltips = function (sPending) {
};
LinkHints.prototype.fnActivateDropDownMenu = function (oTooltip) {
// to enable link hint navigation for drop down menu, we must expand
// to enable link hint navigation for drop down menu, we must expand
// like if they were hovered
oTooltip.parentElement.parentElement.classList.toggle("block");
};
@ -810,7 +810,7 @@ LinkHints.prototype.onkeypress = function(oEvent){
}
var activeElementType = ((document.activeElement && document.activeElement.nodeName) || "");
// link hints are disabled for input and textareas for obvious reasons.
// Maybe we must add other types here in the future
if (oEvent.key === this.sLinkHintKey && activeElementType !== "INPUT" && activeElementType !== "TEXTAREA") {
@ -818,7 +818,7 @@ LinkHints.prototype.onkeypress = function(oEvent){
this.fnToggleAllTooltips();
} else if (this.bTooltipsOn === true) {
// the user tries to reach a tooltip
this.sPending += oEvent.key;
var oTooltip = this.oTooltipMap[this.sPending];
@ -856,8 +856,8 @@ function Hotkeys(oKeyMap){
// these are the hotkeys provided by the backend
Object.keys(this.oKeyMap).forEach(function(sKey){
var action = this.oKeyMap[sKey];
var action = this.oKeyMap[sKey];
// We replace the actions with callback functions to unify
// the hotkey execution
this.oKeyMap[sKey] = function(oEvent) {
@ -872,7 +872,7 @@ function Hotkeys(oKeyMap){
if (window[action]) {
window[action].call(this);
}
// Or a SAP event
var sUiSapEvent = this.getSapEvent(action);
if (sUiSapEvent) {
@ -889,7 +889,7 @@ function Hotkeys(oKeyMap){
Hotkeys.prototype.showHotkeys = function() {
var elHotkeys = document.querySelector('#hotkeys');
if (elHotkeys) {
elHotkeys.style.display = (elHotkeys.style.display) ? '' : 'none';
}
@ -906,7 +906,7 @@ Hotkeys.prototype.getSapEvent = function(sSapEvent) {
var aSapEvents = document.querySelectorAll('a[href^="sapevent:' + sSapEvent + '"]');
var aFilteredAndNormalizedSapEvents =
var aFilteredAndNormalizedSapEvents =
[].map.call(aSapEvents, function(oSapEvent){
return fnNormalizeSapEventHref(sSapEvent, oSapEvent);
})
@ -931,7 +931,7 @@ Hotkeys.prototype.onkeydown = function(oEvent){
return;
}
var
var
sKey = oEvent.key || String.fromCharCode(oEvent.keyCode),
fnHotkey = this.oKeyMap[sKey];
@ -948,7 +948,7 @@ function setKeyBindings(oKeyMap){
}
/*
/*
Patch / git add -p
*/
@ -971,7 +971,7 @@ function Patch() {
PATCH_ADD_ALL: 'patch_add_all',
PATCH_REMOVE_ALL: 'patch_remove_all'
};
this.ACTION = {
PATCH_STAGE: 'patch_stage'
};
@ -999,7 +999,7 @@ Patch.prototype.registerClickHandlerSingleLine = function(){
Patch.prototype.registerClickHandlerAllFile = function(){
// registers the link handlers for add and remove all changes for a file
// registers the link handlers for add and remove all changes for a file
this.registerClickHandlerForPatchLinkAll('#' + this.ID.PATCH_ADD_ALL, this.ADD_REMOVE);
this.registerClickHandlerForPatchLinkAll('#' + this.ID.PATCH_REMOVE_ALL, this.REMOVE_ADD);
@ -1007,14 +1007,14 @@ Patch.prototype.registerClickHandlerAllFile = function(){
};
Patch.prototype.registerClickHandlerForPatchLink = function(oClassCombination) {
// register onclick handler. When a link is clicked it is
// register onclick handler. When a link is clicked it is
// deactivated and its corresponding link gets active
//
// e.g. if you click on 'add' add is deactivated and 'remove'
// e.g. if you click on 'add' add is deactivated and 'remove'
// is activated.
var elLinkAll = document.querySelectorAll('.' + this.CSS_CLASS.PATCH + ' a.' + oClassCombination.sClassLinkClicked);
[].forEach.call(elLinkAll,function(elLink){
elLink.addEventListener('click',function(oEvent){
@ -1025,7 +1025,7 @@ Patch.prototype.registerClickHandlerForPatchLink = function(oClassCombination) {
};
Patch.prototype.togglePatchActive = function(oEvent, elClicked, elCorrespondingLink){
Patch.prototype.togglePatchActive = function(oEvent, elClicked, elCorrespondingLink){
if (!elClicked.classList.contains(this.CSS_CLASS.PATCH_ACTIVE)){
elClicked.classList.toggle(this.CSS_CLASS.PATCH_ACTIVE);
@ -1046,7 +1046,7 @@ Patch.prototype.togglePatchActiveForClassLink = function(oEvent, elClicked, oCla
Patch.prototype.getCorrespodingLinkId = function(sClickedLinkId, oClassCombination){
// e.g.
// e.g.
//
// add_patch_z_test_git_add_p.prog.abap_28 => remove_patch_z_test_git_add_p.prog.abap_28
//
@ -1066,7 +1066,7 @@ Patch.prototype.patchLinkClickAll = function(oClassCombination) {
var sTableId = oEvent.srcElement.parentElement.parentElement.parentElement.parentElement.id;
var elAddAll = document.querySelectorAll('#' + this.escapeDots(sTableId) + ' a.' + oClassCombination.sClassLinkClicked);
[].forEach.call(elAddAll,function(elem){
this.togglePatchActiveForClassLink(oEvent, elem, oClassCombination);
}.bind(this));

View File

@ -0,0 +1,118 @@
"! Change transport system API
CLASS zcl_abapgit_cts_api DEFINITION
PUBLIC
FINAL
CREATE PRIVATE
GLOBAL FRIENDS zcl_abapgit_factory.
PUBLIC SECTION.
INTERFACES:
zif_abapgit_cts_api.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_cts_api IMPLEMENTATION.
METHOD zif_abapgit_cts_api~get_current_transport_for_obj.
DATA: lv_object_lockable TYPE abap_bool,
lv_locked TYPE abap_bool,
lv_transport_request TYPE trkorr,
lv_task TYPE trkorr,
lv_tr_object_name TYPE trobj_name.
lv_tr_object_name = iv_object_name.
CALL FUNCTION 'TR_CHECK_OBJECT_LOCK'
EXPORTING
wi_pgmid = iv_program_id
wi_object = iv_object_type
wi_objname = lv_tr_object_name
IMPORTING
we_lockable_object = lv_object_lockable
we_locked = lv_locked
we_lock_order = lv_transport_request
we_lock_task = lv_task
EXCEPTIONS
empty_key = 1
no_systemname = 2
no_systemtype = 3
unallowed_lock_order = 4
OTHERS = 5.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
IF lv_locked = abap_false.
zcx_abapgit_exception=>raise( |Object { iv_program_id }-{ iv_object_type }-{ iv_object_name } is not locked| ).
ENDIF.
IF lv_object_lockable = abap_false.
zcx_abapgit_exception=>raise( |Object type { iv_program_id }-{ iv_object_type } not lockable| ).
ENDIF.
IF lv_task IS NOT INITIAL AND lv_task <> lv_transport_request AND iv_resolve_task_to_request = abap_false.
rv_transport = lv_task.
ELSE.
rv_transport = lv_transport_request.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_cts_api~is_object_locked_in_transport.
DATA: ls_object_key TYPE e071,
lv_type_check_result TYPE c LENGTH 1,
ls_lock_key TYPE tlock_int,
lv_lock_flag TYPE c LENGTH 1.
ls_object_key-pgmid = iv_program_id.
ls_object_key-object = iv_object_type.
ls_object_key-obj_name = iv_object_name.
CALL FUNCTION 'TR_CHECK_TYPE'
EXPORTING
wi_e071 = ls_object_key
IMPORTING
pe_result = lv_type_check_result
we_lock_key = ls_lock_key.
IF lv_type_check_result <> 'L'.
zcx_abapgit_exception=>raise( |Object type { iv_program_id }-{ iv_object_type } not lockable| ).
ENDIF.
CALL FUNCTION 'TRINT_CHECK_LOCKS'
EXPORTING
wi_lock_key = ls_lock_key
IMPORTING
we_lockflag = lv_lock_flag
EXCEPTIONS
empty_key = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |TRINT_CHECK_LOCKS: { sy-subrc }| ).
ENDIF.
rv_locked = boolc( lv_lock_flag <> space ).
ENDMETHOD.
METHOD zif_abapgit_cts_api~is_object_type_lockable.
DATA: ls_object_key TYPE e071,
lv_type_check_result TYPE c LENGTH 1.
ls_object_key-pgmid = iv_program_id.
ls_object_key-object = iv_object_type.
ls_object_key-obj_name = '*'.
CALL FUNCTION 'TR_CHECK_TYPE'
EXPORTING
wi_e071 = ls_object_key
IMPORTING
pe_result = lv_type_check_result.
rv_lockable = boolc( lv_type_check_result = 'L' ).
ENDMETHOD.
METHOD zif_abapgit_cts_api~is_chrec_possible_for_package.
rv_possible = zcl_abapgit_factory=>get_sap_package( iv_package )->are_changes_recorded_in_tr_req( ).
ENDMETHOD.
ENDCLASS.

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOCLASS>
<CLSNAME>ZCL_ABAPGIT_CTS_API</CLSNAME>
<VERSION>1</VERSION>
<LANGU>E</LANGU>
<DESCRIPT>Change transport system API</DESCRIPT>
<STATE>1</STATE>
<CLSFINAL>X</CLSFINAL>
<CLSCCINCL>X</CLSCCINCL>
<FIXPT>X</FIXPT>
<UNICODE>X</UNICODE>
</VSEOCLASS>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -54,6 +54,9 @@ CLASS zcl_abapgit_factory DEFINITION
CLASS-METHODS get_stage_logic
RETURNING
VALUE(ri_logic) TYPE REF TO zif_abapgit_stage_logic .
CLASS-METHODS get_cts_api
RETURNING
VALUE(ri_cts_api) TYPE REF TO zif_abapgit_cts_api.
PRIVATE SECTION.
TYPES:
@ -96,6 +99,7 @@ CLASS zcl_abapgit_factory DEFINITION
CLASS-DATA gt_syntax_check TYPE tty_syntax_check .
CLASS-DATA gi_branch_overview TYPE REF TO zif_abapgit_branch_overview .
CLASS-DATA gi_stage_logic TYPE REF TO zif_abapgit_stage_logic .
CLASS-DATA gi_cts_api TYPE REF TO zif_abapgit_cts_api.
CLASS-DATA gi_adhoc_code_inspector TYPE REF TO zif_abapgit_code_inspector.
ENDCLASS.
@ -218,6 +222,13 @@ CLASS zcl_abapgit_factory IMPLEMENTATION.
ENDMETHOD.
METHOD get_cts_api.
IF gi_cts_api IS NOT BOUND.
CREATE OBJECT gi_cts_api TYPE zcl_abapgit_cts_api.
ENDIF.
ri_cts_api = gi_cts_api.
ENDMETHOD.
METHOD get_adhoc_code_inspector.
@ -246,6 +257,4 @@ CLASS zcl_abapgit_factory IMPLEMENTATION.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@ -24,12 +24,15 @@ CLASS zcl_abapgit_injector DEFINITION
CLASS-METHODS set_stage_logic
IMPORTING
!ii_logic TYPE REF TO zif_abapgit_stage_logic .
CLASS-METHODS set_cts_api
IMPORTING
ii_cts_api TYPE REF TO zif_abapgit_cts_api.
PRIVATE SECTION.
ENDCLASS.
CLASS ZCL_ABAPGIT_INJECTOR IMPLEMENTATION.
CLASS zcl_abapgit_injector IMPLEMENTATION.
METHOD set_code_inspector.
@ -115,4 +118,8 @@ CLASS ZCL_ABAPGIT_INJECTOR IMPLEMENTATION.
zcl_abapgit_factory=>gi_tadir = ii_tadir.
ENDMETHOD.
METHOD set_cts_api.
zcl_abapgit_factory=>gi_cts_api = ii_cts_api.
ENDMETHOD.
ENDCLASS.

View File

@ -0,0 +1,42 @@
"! Change transport system API
INTERFACE zif_abapgit_cts_api PUBLIC.
METHODS:
"! Returns the transport request / task the object is currently locked in
"! @parameter iv_program_id | Program ID
"! @parameter iv_object_type | Object type
"! @parameter iv_object_name | Object name
"! @parameter iv_resolve_task_to_request | Return the transport request number if the object is locked in a task
"! @parameter rv_transport | Transport request / task
"! @raising zcx_abapgit_exception | Object is not locked in a transport
get_current_transport_for_obj IMPORTING iv_program_id TYPE pgmid DEFAULT 'R3TR'
iv_object_type TYPE trobjtype
iv_object_name TYPE sobj_name
iv_resolve_task_to_request TYPE abap_bool DEFAULT abap_true
RETURNING VALUE(rv_transport) TYPE trkorr
RAISING zcx_abapgit_exception,
"! Check if the object is currently locked in a transport
"! @parameter iv_program_id | Program ID
"! @parameter iv_object_type | Object type
"! @parameter iv_object_name | Object name
"! @parameter rv_locked | Object is locked
"! @raising zcx_abapgit_exception | Object type is not lockable
is_object_locked_in_transport IMPORTING iv_program_id TYPE pgmid DEFAULT 'R3TR'
iv_object_type TYPE trobjtype
iv_object_name TYPE sobj_name
RETURNING VALUE(rv_locked) TYPE abap_bool
RAISING zcx_abapgit_exception,
"! Check if the object type is lockable
"! @parameter iv_program_id | Program ID
"! @parameter iv_object_type | Object type
"! @parameter rv_lockable | Lockable
is_object_type_lockable IMPORTING iv_program_id TYPE pgmid DEFAULT 'R3TR'
iv_object_type TYPE trobjtype
RETURNING VALUE(rv_lockable) TYPE abap_bool,
"! Check if change recording is possible for the given package
"! @parameter iv_package | Package
"! @parameter rv_possible | Change recording is possible
"! @raising zcx_abapgit_exception | Package could not be loaded
is_chrec_possible_for_package IMPORTING iv_package TYPE devclass
RETURNING VALUE(rv_possible) TYPE abap_bool
RAISING zcx_abapgit_exception.
ENDINTERFACE.

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_INTF" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOINTERF>
<CLSNAME>ZIF_ABAPGIT_CTS_API</CLSNAME>
<VERSION>1</VERSION>
<LANGU>E</LANGU>
<DESCRIPT>Change transport system API</DESCRIPT>
<EXPOSURE>2</EXPOSURE>
<STATE>1</STATE>
<UNICODE>X</UNICODE>
</VSEOINTERF>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -481,6 +481,7 @@ INTERFACE zif_abapgit_definitions PUBLIC.
jump TYPE string VALUE 'jump',
jump_pkg TYPE string VALUE 'jump_pkg',
jump_transport TYPE string VALUE 'jump_transport',
url TYPE string VALUE 'url',
END OF c_action .