From 84c66a73ba4ba3b17dc779046ab71f49f14fa474 Mon Sep 17 00:00:00 2001 From: oblomov <102328295+oblomov-dev@users.noreply.github.com> Date: Wed, 17 May 2023 19:21:01 +0200 Subject: [PATCH] demos (#232) * Update README.md * Update README.md * Update README.md * Update README.md * bugfixes and demos * demos --- README.md | 3 +- src/00/z2ui5_cl_app_demo_00.clas.abap | 4 +- src/00/z2ui5_cl_app_demo_49.clas.abap | 111 ++++++++++++++++-- src/00/z2ui5_cl_xml_view.clas.abap | 4 + src/z2ui5_cl_http_handler.clas.abap | 12 +- ...z2ui5_cl_http_handler.clas.locals_imp.abap | 33 ++++-- src/z2ui5_if_client.intf.abap | 36 +++--- 7 files changed, 164 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 9880aab7..c4ae9aca 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,8 @@ Development of UI5 Apps in pure ABAP. Follow this project on [Twitter](https://t #### More * Find abap2UI5 in the ABAP Open Source Projects [(dotabap.org)](https://dotabap.org/) * Static Analysis & Continuous Integration with abaplint [(abaplint.app/abap2UI5)](https://abaplint.app/stats/oblomov-dev/abap2UI5) -* Featured in the Boring Enterprise Nerdletter [(newsletter - 08.03.2023)](https://boringenterprisenerds.substack.com/p/34-abap2ui5-sap-cva-burnout-c2c-shortwave) +* Part of the SAP Developer Code Challenge [(SCN - 17.05.2023)](https://groups.community.sap.com/t5/application-development/sap-developer-code-challenge-open-source-abap-week-2/m-p/260727#M1372) +* Featured in the Boring Enterprise Nerdletter [(newsletter - 08.03.2023)](https://boringenterprisenerds.substack.com/p/34-abap2ui5-sap-cva-burnout-c2c-shortwave) * Featured in the SAP Developer News [(youtube - 26.01.2023)](https://www.youtube.com/watch?v=6BDK55xYttM) * Development of UI5 Selection Screens in pure ABAP (former version) [(Blog SCN - 22.01.2023)](https://blogs.sap.com/2023/01/22/abap2ui5-project-development-of-ui5-selection-screens-in-pure-abap-no-app-deployment-or-javascript-needed/) diff --git a/src/00/z2ui5_cl_app_demo_00.clas.abap b/src/00/z2ui5_cl_app_demo_00.clas.abap index dbde278e..1509cbc6 100644 --- a/src/00/z2ui5_cl_app_demo_00.clas.abap +++ b/src/00/z2ui5_cl_app_demo_00.clas.abap @@ -260,6 +260,8 @@ CLASS Z2UI5_CL_APP_DEMO_00 IMPLEMENTATION. growfactor = '3' styleclass = 'sapUiTinyMargin' ). - client->set_next( VALUE #( xml_main = page->get_root( )->xml_get( ) ) ). + client->set_next( VALUE #( + path = `/` + xml_main = page->get_root( )->xml_get( ) ) ). ENDMETHOD. ENDCLASS. diff --git a/src/00/z2ui5_cl_app_demo_49.clas.abap b/src/00/z2ui5_cl_app_demo_49.clas.abap index aee6d706..7ceb784e 100644 --- a/src/00/z2ui5_cl_app_demo_49.clas.abap +++ b/src/00/z2ui5_cl_app_demo_49.clas.abap @@ -138,6 +138,7 @@ CLASS z2ui5_cl_app_demo_49 DEFINITION PUBLIC. METHODS z2ui5_on_render_detail. METHODS z2ui5_on_render_pop_setup. METHODS z2ui5_on_render_pop_filter. + METHODS z2ui5_on_render_pop_detail. METHODS z2ui5_on_render_pop_layout. METHODS z2ui5_set_download_csv IMPORTING @@ -162,6 +163,9 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. me->client = client. app-get = client->get( ). app-view_popup = ``. + app-next-path = `/z2ui5_cl_app_demo_49`. + app-next-title = `List Report`. + IF app-check_initialized = abap_false. app-check_initialized = abap_true. @@ -174,6 +178,7 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. z2ui5_on_render( ). + client->set_next( app-next ). CLEAR app-get. CLEAR app-next. @@ -199,7 +204,7 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. WHEN 'BUTTON_CUSTOM'. client->popup_message_box( `custom action called` ). - WHEN 'BUTTON_START'. + WHEN 'BUTTON_START'. z2ui5_set_data( ). WHEN 'BUTTON_DOWNLOAD'. @@ -236,7 +241,12 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. z2ui5_set_detail( ). app-view_main = 'DETAIL'. + WHEN 'POPUP_DETAIL'. + app-next-popup_open_by_id = app-get-event_data. + app-view_popup = 'POPUP_LAYOUT'. + WHEN 'POPUP_LAYOUT'. + app-next-popup_open_by_id = `btn_layout`. app-view_popup = 'POPUP_LAYOUT'. WHEN 'POPUP_FILTER'. @@ -256,6 +266,7 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. app-view_popup = ''. WHEN 'BACK'. + " app-next-path = `test`. client->nav_app_leave( client->get_app( app-get-id_prev_app_stack ) ). ENDCASE. @@ -265,7 +276,7 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. METHOD z2ui5_on_init. - app-view_main = 'MAIN'. + init_table_output( ). ms_view-title = `Standart`. @@ -284,6 +295,35 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. ( key = '<500' text = '<500' selkz = abap_true ) ). + + + " IF app-view_main IS INITIAL. + DATA(lv_url) = z2ui5_cl_http_handler=>client-t_header[ name = `referer` ]-value. + SPLIT lv_url AT `/z2ui5_cl_app_demo_49/` INTO DATA(lv_dummy1) DATA(lv_dummy2). + SPLIT lv_dummy2 AT `(` INTO DATA(lv_view) DATA(lv_token). + IF lv_view IS NOT INITIAL. + app-view_main = lv_view. + SPLIT lv_token AT `(` INTO DATA(lv_token2) lv_dummy1. + SPLIT lv_token2 AT `)` INTO lv_token lv_dummy1. + ms_detail-uuid = lv_token. + IF ms_detail-uuid IS NOT INITIAL. + z2ui5_set_data( ). + + ms_detail = mt_table[ uuid = ms_detail-uuid ]. + + SELECT SINGLE FROM z2ui5_t_draft + FIELDS * + WHERE uuid = @ms_detail-uuid + INTO CORRESPONDING FIELDS OF @ms_detail + . + + ENDIF. + " ENDIF. + ELSE. + app-view_main = 'MAIN'. + ENDIF. + + * mt_token_sugg = VALUE #( * ( key = 'VAL1' text = 'value_1' ) * ( key = 'VAL2' text = 'value_2' ) @@ -304,8 +344,12 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. z2ui5_on_render_pop_setup( ). WHEN `POPUP_LAYOUT`. z2ui5_on_render_pop_layout( ). + WHEN `POPUP_DETAIL`. + z2ui5_on_render_pop_detail( ). ENDCASE. + app-next-path = app-next-path && `/` && app-view_main. + CASE app-view_main. WHEN 'MAIN'. z2ui5_on_render_main( ). @@ -313,6 +357,8 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. z2ui5_on_render_detail( ). ENDCASE. + + ENDMETHOD. METHOD init_table_output. @@ -379,7 +425,8 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. DATA(header_title) = page->title( ns = 'f' )->get( )->dynamic_page_title( ). - header_title->heading( ns = 'f' )->hbox( )->title( ms_view-title )->button( type = `Transparent` icon = `sap-icon://dropdown` ). + header_title->heading( ns = 'f' )->hbox( )->title( ms_view-title + )->button( id = `btn_layout` press = client->_event( `POPUP_LAYOUT` ) type = `Transparent` icon = `sap-icon://dropdown` ). header_title->expanded_content( 'f' )->label( text = 'Drafts of abap2UI5' ). @@ -388,8 +435,7 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. )->label( text = 'Drafts of abap2UI5' ). header_title->actions( ns = 'f' )->overflow_toolbar( - )->button( text = `Layout` type = `Emphasized` press = client->_event( `POPUP_LAYOUT` ) - + )->button( text = `Custom Function` press = client->_event( `BUTTON_CUSTOM` ) ). DATA(lo_box) = page->header( )->dynamic_page_header( pinnable = abap_true @@ -436,9 +482,9 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. width = `17.5rem` id = `SEARCH` )->toolbar_spacer( - )->button( - text = `Custom Action` - press = client->_event( 'BUTTON_CUSTOM' ) +* )->button( +* text = `Custom Action` +* press = client->_event( 'BUTTON_CUSTOM' ) )->button( text = `Anlegen` @@ -473,7 +519,11 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. IF lr_field->editable = abap_true. lo_cells->input( `{` && lr_field->name && `}` ). ELSE. - lo_cells->text( `{` && lr_field->name && `}` ). + " lo_cells->text( `{` && lr_field->name && `}` ). + lo_cells->link( text = `{` && lr_field->name && `}` + " press = client->_event( val = `POPUP_DETAIL` data = `${` && lr_field->name && `}` ) ). + press = client->_event( val = `POPUP_DETAIL` data = `${$source>/id}` ) ). + " press = client->_event( val = `POPUP_DETAIL` data = `$event` ) ). ENDIF. ENDLOOP. @@ -484,6 +534,8 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. METHOD z2ui5_on_render_detail. + app-next-path = app-next-path && `(` && ms_detail-uuid && `)`. + DATA(view) = z2ui5_cl_xml_view=>factory( )->page( title = 'abap2UI5 - List Report' @@ -719,11 +771,50 @@ CLASS z2ui5_cl_app_demo_49 IMPLEMENTATION. ENDMETHOD. + METHOD z2ui5_on_render_pop_detail. + + DATA(lo_popup) = z2ui5_cl_xml_view=>factory_popup( ). + + lo_popup->popover( placement = `Bottom` title = 'abap2UI5 - Layout' contentwidth = `50%` + )->input( description = `Name` value = client->_bind( mv_layout_name ) + )->button( text = `Save` press = client->_event( `BUTTON_SAVE_LAYOUT` ) + )->table( + mode = 'SingleSelectLeft' + items = client->_bind( mt_db_layout ) + )->columns( + )->column( )->text( 'Name' )->get_parent( + )->column( )->text( 'User' )->get_parent( + )->column( )->text( 'Default' )->get_parent( + " )->column( )->text( 'Description' )->get_parent( + )->get_parent( + )->items( )->column_list_item( selected = '{SELKZ}' + )->cells( + " )->checkbox( '{SELKZ}' + )->text( '{NAME}' + )->text( '{USER}' + )->text( '{DEFAULT}' + " )->text( '{DESCR}' + )->get_parent( )->get_parent( )->get_parent( )->get_parent( + )->footer( )->overflow_toolbar( + )->toolbar_spacer( + )->button( + text = 'load' + press = client->_event( 'POPUP_LAYOUT_LOAD' ) + type = 'Emphasized' + )->button( + text = 'close' + press = client->_event( 'POPUP_LAYOUT_CONTINUE' ) + type = 'Emphasized' ). + + app-next-xml_popup = lo_popup->get_root( )->xml_get( ). + + ENDMETHOD. + METHOD z2ui5_on_render_pop_layout. DATA(lo_popup) = z2ui5_cl_xml_view=>factory_popup( ). - lo_popup->dialog( title = 'abap2UI5 - Layout' contentwidth = `50%` + lo_popup->popover( placement = `Bottom` title = 'abap2UI5 - Layout' contentwidth = `50%` )->input( description = `Name` value = client->_bind( mv_layout_name ) )->button( text = `Save` press = client->_event( `BUTTON_SAVE_LAYOUT` ) )->table( diff --git a/src/00/z2ui5_cl_xml_view.clas.abap b/src/00/z2ui5_cl_xml_view.clas.abap index e051fd80..1c054488 100644 --- a/src/00/z2ui5_cl_xml_view.clas.abap +++ b/src/00/z2ui5_cl_xml_view.clas.abap @@ -733,6 +733,8 @@ CLASS z2ui5_cl_xml_view DEFINITION href TYPE clike OPTIONAL target TYPE clike OPTIONAL enabled TYPE clike OPTIONAL + press TYPE clike OPTIONAL + id TYPE clike OPTIONAL ns TYPE clike OPTIONAL RETURNING VALUE(result) TYPE REF TO z2ui5_cl_xml_view. @@ -1688,6 +1690,8 @@ CLASS z2ui5_cl_xml_view IMPLEMENTATION. ( n = `text` v = text ) ( n = `target` v = target ) ( n = `href` v = href ) + ( n = `press` v = press ) + ( n = `id` v = id ) ( n = `enabled` v = lcl_utility=>get_json_boolean( enabled ) ) ) ). diff --git a/src/z2ui5_cl_http_handler.clas.abap b/src/z2ui5_cl_http_handler.clas.abap index 65e52a0a..508a37e3 100644 --- a/src/z2ui5_cl_http_handler.clas.abap +++ b/src/z2ui5_cl_http_handler.clas.abap @@ -19,10 +19,10 @@ CLASS z2ui5_cl_http_handler DEFINITION CLASS-METHODS http_get IMPORTING - title TYPE clike DEFAULT `abap2UI5` t_config TYPE z2ui5_if_client=>ty_t_name_value OPTIONAL content_security_policy TYPE clike OPTIONAL check_logging TYPE abap_bool DEFAULT abap_false + title TYPE string DEFAULT `abap2UI5` RETURNING VALUE(r_result) TYPE string. @@ -89,13 +89,18 @@ CLASS z2ui5_cl_http_handler IMPLEMENTATION. ENDIF. IF content_security_policy IS NOT SUPPLIED. - DATA(lv_sec_policy) = ``. + DATA(lv_sec_policy) = ``. ELSE. lv_sec_policy = content_security_policy. ENDIF. DATA(lv_url) = z2ui5_lcl_utility=>get_header_val( '~path' ). DATA(lv_app) = z2ui5_lcl_utility=>get_param_val( 'app' ). + IF lv_app IS INITIAL. + DATA(lv_path) = z2ui5_lcl_utility=>get_header_val( '~path_info' ). + SPLIT lv_path AT `/` INTO lv_app DATA(lv_dummy). + ENDIF. z2ui5_lcl_fw_db=>cleanup( ). r_result = `` && |\n| && @@ -129,6 +134,8 @@ CLASS z2ui5_cl_http_handler IMPLEMENTATION. ` sap.ui.controller("z2ui5_controller", {` && |\n| && |\n| && ` onAfterRendering: function () {` && |\n| && + ` if(sap.z2ui5.oResponse.title != ""){ document.title = sap.z2ui5.oResponse.title; }` && |\n| && + ` if(sap.z2ui5.oResponse.path != ""){ window.history.replaceState( "" , "" , window.location.origin + sap.z2ui5.oResponse.path + window.location.search ); }` && |\n| && ` var oView = this.getView();` && |\n| && ` try {` && |\n| && ` if (sap.z2ui5.oResponse.oCursor) {` && |\n| && @@ -310,6 +317,7 @@ CLASS z2ui5_cl_http_handler IMPLEMENTATION. ` jQuery.sap.require("sap.m.MessageBox");` && |\n| && ` var oView = sap.ui.xmlview({viewContent:xml});` && |\n| && ` sap.z2ui5.Roundtrip = oView.getController().Roundtrip;` && |\n| && + ` sap.z2ui5.pathname = window.location.pathname;` && |\n| && ` sap.z2ui5.Roundtrip();` && |\n| && |\n| && ` });` && |\n| && diff --git a/src/z2ui5_cl_http_handler.clas.locals_imp.abap b/src/z2ui5_cl_http_handler.clas.locals_imp.abap index d9875086..dd8893f9 100644 --- a/src/z2ui5_cl_http_handler.clas.locals_imp.abap +++ b/src/z2ui5_cl_http_handler.clas.locals_imp.abap @@ -247,7 +247,7 @@ CLASS z2ui5_lcl_utility IMPLEMENTATION. METHOD get_header_val. - result = z2ui5_cl_http_handler=>client-t_header[ name = v ]-value. + result = to_lower( z2ui5_cl_http_handler=>client-t_header[ name = v ]-value ). ENDMETHOD. @@ -1022,11 +1022,11 @@ CLASS z2ui5_lcl_fw_app IMPLEMENTATION. source_line = DATA(lv_line) ). - if client->get_app( client->get( )-id_prev_app ) is bound. - data(lv_check_back) = `true`. - else. - lv_check_back = `false`. - endif. + IF client->get_app( client->get( )-id_prev_app ) IS BOUND. + DATA(lv_check_back) = `true`. + ELSE. + lv_check_back = `false`. + ENDIF. DATA(lv_descr) = ms_error-x_error->get_text( ) && ` -------------------------------------------------------------------------------------------- Source Code Position: ` && @@ -1306,6 +1306,20 @@ CLASS z2ui5_lcl_fw_handler IMPLEMENTATION. lo_ui5_model->add_attribute( n = `SET_PREV_VIEW` v = `true` apos_active = abap_false ). ENDIF. + + + IF ms_next-s_set-path IS NOT INITIAL. + DATA(lv_path) = z2ui5_lcl_utility=>get_header_val( '~path' ). + DATA(lv_path_info) = z2ui5_lcl_utility=>get_header_val( '~path_info' ). + REPLACE lv_path_info IN lv_path WITH ``. + SHIFT lv_path RIGHT DELETING TRAILING `/`. + SHIFT lv_path LEFT DELETING LEADING ` `. + ms_next-s_set-path = lv_path && ms_next-s_set-path. + ENDIF. + + lo_ui5_model->add_attribute( n = `path` v = ms_next-s_set-path ). + lo_ui5_model->add_attribute( n = `title` v = ms_next-s_set-title ). + result = lo_ui5_model->get_root( )->stringify( ). z2ui5_lcl_fw_db=>create( id = ms_db-id db = ms_db ). @@ -1431,7 +1445,7 @@ CLASS z2ui5_lcl_fw_handler IMPLEMENTATION. result = NEW #( ). result->ms_db-o_app = ms_next-o_call_app. - CLEAR ms_next. + z2ui5_lcl_fw_db=>create( id = ms_db-id db = ms_db ). DATA(ls_draft) = z2ui5_lcl_fw_db=>read( id = result->ms_db-o_app->id check_load_app = abap_false ). @@ -1443,6 +1457,9 @@ CLASS z2ui5_lcl_fw_handler IMPLEMENTATION. result->ms_db-id_prev_app = ms_db-id. result->ms_db-id_prev = ms_db-id. + " result->ms_next-s_set-path = `test`. "ms_next-s_set-path. + CLEAR ms_next. + ENDMETHOD. METHOD set_app_call. @@ -1484,7 +1501,7 @@ CLASS z2ui5_lcl_fw_handler IMPLEMENTATION. DATA(lr_in) = REF #( value ). LOOP AT ms_db-t_attri REFERENCE INTO DATA(lr_attri) - where bind_type <> cs_bind_type-one_time. + WHERE bind_type <> cs_bind_type-one_time. FIELD-SYMBOLS TYPE any. DATA(lv_name) = c_prefix && to_upper( lr_attri->name ). diff --git a/src/z2ui5_if_client.intf.abap b/src/z2ui5_if_client.intf.abap index 159c8d34..83afcfe6 100644 --- a/src/z2ui5_if_client.intf.abap +++ b/src/z2ui5_if_client.intf.abap @@ -17,27 +17,29 @@ INTERFACE z2ui5_if_client id_prev_app TYPE string, id_prev_app_stack TYPE string, t_scroll_pos TYPE ty_t_name_value, - t_req_param type ty_t_name_value, - t_req_header type ty_t_name_value, + t_req_param TYPE ty_t_name_value, + t_req_header TYPE ty_t_name_value, END OF ty_s_get. TYPES: BEGIN OF ty_S_next, xml_main TYPE string, xml_popup TYPE string, - popup_open_by_id type string, + popup_open_by_id TYPE string, check_set_prev_view TYPE abap_bool, t_scroll_pos TYPE ty_t_name_value, - BEGIN OF s_cursor_pos, - id TYPE string, - cursorpos TYPE string, - selectionstart TYPE string, - selectionend TYPE string, - END OF s_cursor_pos, - begin of s_timer, - interval_ms type string, - event_finished type string, - end of s_timer, + title TYPE string, + path TYPE string, + begin OF s_cursor_pos, + id TYPE string, + cursorpos TYPE string, + selectionstart TYPE string, + selectionend TYPE string, + END OF s_cursor_pos, + BEGIN OF s_timer, + interval_ms TYPE string, + event_finished TYPE string, + END OF s_timer, END OF ty_s_next. METHODS set_next @@ -56,7 +58,7 @@ INTERFACE z2ui5_if_client METHODS nav_app_leave IMPORTING - app type ref to z2ui5_if_app. + app TYPE REF TO z2ui5_if_app. METHODS nav_app_call IMPORTING @@ -77,9 +79,9 @@ INTERFACE z2ui5_if_client IMPORTING val TYPE data path TYPE abap_bool DEFAULT abap_false - check_gen_data type abap_bool OPTIONAL + check_gen_data TYPE abap_bool OPTIONAL RETURNING - VALUE(result) TYPE string. + VALUE(result) TYPE string. METHODS _bind_one IMPORTING @@ -91,7 +93,7 @@ INTERFACE z2ui5_if_client METHODS _event IMPORTING val TYPE clike - data type clike optional + data TYPE clike OPTIONAL RETURNING VALUE(result) TYPE string.