From 4e45c29095c86a835de5c04fa7a1d8f0c5568291 Mon Sep 17 00:00:00 2001 From: Irakli Chalagashvili Date: Thu, 16 Dec 2021 20:16:20 +0400 Subject: [PATCH 01/12] ENG-3041 call webui clone api --- src/api/pages.js | 12 +++++++++++- src/state/pages/actions.js | 6 ++++-- test/api/pages.test.js | 18 +++++++++++++++++- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/api/pages.js b/src/api/pages.js index 6ce09077c..bf766a150 100644 --- a/src/api/pages.js +++ b/src/api/pages.js @@ -1,4 +1,4 @@ -import { makeRequest, METHODS } from '@entando/apimanager'; +import { makeRequest, makeMockRequest, METHODS } from '@entando/apimanager'; import { HOMEPAGE_PAYLOAD, LOGIN_PAYLOAD, SERVICE_PAYLOAD, CONTACTS_PAYLOAD, NOTFOUND_PAYLOAD, ERROR_PAYLOAD, DASHBOARD_PAYLOAD, FREE_PAGES_PAYLOAD, @@ -320,3 +320,13 @@ export const postWebuiPage = pageObject => makeRequest({ domain: WEBUI_APP_MANAGEMENT_URL, useAuthentication: true, }); + +export const postWebuiClonePage = (pageCode, pageObject) => makeMockRequest({ + // @TODO remove this once BE API exists + uri: `/api/pages/${pageCode}/clone`, // @TODO double check this + method: METHODS.POST, + body: pageObject, + mockResponse: {}, + domain: WEBUI_APP_MANAGEMENT_URL, + useAuthentication: true, +}); diff --git a/src/state/pages/actions.js b/src/state/pages/actions.js index a00b05844..95d2c9ae7 100644 --- a/src/state/pages/actions.js +++ b/src/state/pages/actions.js @@ -6,7 +6,7 @@ import { getPage, getPageChildren, setPagePosition, postPage, deletePage, getFreePages, getPageSettings, putPage, putPageStatus, getViewPages, getSearchPages, putPageSettings, patchPage, getPageSEO, postPageSEO, putPageSEO, postClonePage, - deleteWebuiPage, postWebuiPage, putWebuiPageStatus, + deleteWebuiPage, postWebuiPage, putWebuiPageStatus, postWebuiClonePage, } from 'api/pages'; import { getStatusMap, @@ -370,7 +370,9 @@ export const sendClonePage = (pageCode, pageData) => dispatch => new Promise(asy titles, }; - const response = await postClonePage(pageCode, requestBody); + const cloneApi = WEBUI_ENABLED ? postWebuiClonePage : postClonePage; + + const response = await cloneApi(pageCode, requestBody); const json = await response.json(); if (response.ok) { diff --git a/test/api/pages.test.js b/test/api/pages.test.js index 4df6da0d8..0fdd0c79d 100644 --- a/test/api/pages.test.js +++ b/test/api/pages.test.js @@ -3,7 +3,7 @@ import { getPage, getPageChildren, setPagePosition, postPage, putPage, patchPage, deletePage, getSearchPages, getPageSettings, getFreePages, getPageConfig, deletePageWidget, putPageWidget, getReferencesPage, restorePageConfig, applyDefaultPageConfig, putPageSettings, deleteWebuiPage, - postWebuiPage, putWebuiPageStatus, + postWebuiPage, putWebuiPageStatus, postWebuiClonePage, } from 'api/pages'; import { CONTACTS_PAYLOAD, FREE_PAGES_PAYLOAD, PAGE_SETTINGS_PAYLOAD, SEARCH_PAGES } from 'test/mocks/pages'; @@ -118,6 +118,22 @@ describe('api/pages', () => { }); }); + describe('postWebuiClonePage', () => { + it('returns a promise', () => { + expect(postWebuiClonePage('contacts', CONTACTS_PAYLOAD)).toBeInstanceOf(Promise); + }); + + it('makes the correct request', () => { + postWebuiPage('contacts', CONTACTS_PAYLOAD); + expect(makeRequest).toHaveBeenCalledWith(expect.objectContaining({ + uri: '/api/pages/contacts/clone', + body: CONTACTS_PAYLOAD, + method: METHODS.POST, + useAuthentication: true, + })); + }); + }); + fdescribe('patchPage', () => { const jsonPatch = [ { From 27060bb2c9a4f5d43b8553ad73e18835e828a6ad Mon Sep 17 00:00:00 2001 From: Irakli Chalagashvili Date: Wed, 22 Dec 2021 00:19:00 +0400 Subject: [PATCH 02/12] ENG-3041 ENG-3038 implement clone and edit webui api --- src/api/pages.js | 21 +++++++++++++++---- src/state/pages/actions.js | 14 +++++++------ .../list/PageTemplateListMenuActions.js | 7 +++---- .../list/PageTemplateListTable.js | 1 + src/ui/pages/common/PageForm.js | 19 +++-------------- src/ui/pages/common/PageTreeActionMenu.js | 19 ++++++++++------- src/ui/pages/edit/PagesEditFormContainer.js | 2 -- test/api/pages.test.js | 19 ++++++++++++++++- 8 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/api/pages.js b/src/api/pages.js index bf766a150..6a57cd6b9 100644 --- a/src/api/pages.js +++ b/src/api/pages.js @@ -1,4 +1,4 @@ -import { makeRequest, makeMockRequest, METHODS } from '@entando/apimanager'; +import { makeRequest, METHODS } from '@entando/apimanager'; import { HOMEPAGE_PAYLOAD, LOGIN_PAYLOAD, SERVICE_PAYLOAD, CONTACTS_PAYLOAD, NOTFOUND_PAYLOAD, ERROR_PAYLOAD, DASHBOARD_PAYLOAD, FREE_PAGES_PAYLOAD, @@ -321,12 +321,25 @@ export const postWebuiPage = pageObject => makeRequest({ useAuthentication: true, }); -export const postWebuiClonePage = (pageCode, pageObject) => makeMockRequest({ - // @TODO remove this once BE API exists - uri: `/api/pages/${pageCode}/clone`, // @TODO double check this +export const postWebuiClonePage = (pageCode, pageObject) => makeRequest({ + uri: `/api/pages/${pageCode}/clone`, method: METHODS.POST, body: pageObject, mockResponse: {}, domain: WEBUI_APP_MANAGEMENT_URL, useAuthentication: true, }); + +export const putWebuiPage = pageObject => makeRequest({ + uri: `/api/pages/${pageObject.code}`, + body: pageObject, + method: METHODS.PUT, + mockResponse: { ...pageObject }, + domain: WEBUI_APP_MANAGEMENT_URL, + useAuthentication: true, + errors: () => ( + fetchPageResponseMap[pageObject.code] ? + [] : + [{ code: 1, message: `no page with the code ${pageObject.code} could be found.` }] + ), +}); diff --git a/src/state/pages/actions.js b/src/state/pages/actions.js index 95d2c9ae7..82a121666 100644 --- a/src/state/pages/actions.js +++ b/src/state/pages/actions.js @@ -6,7 +6,7 @@ import { getPage, getPageChildren, setPagePosition, postPage, deletePage, getFreePages, getPageSettings, putPage, putPageStatus, getViewPages, getSearchPages, putPageSettings, patchPage, getPageSEO, postPageSEO, putPageSEO, postClonePage, - deleteWebuiPage, postWebuiPage, putWebuiPageStatus, postWebuiClonePage, + deleteWebuiPage, postWebuiPage, putWebuiPageStatus, postWebuiClonePage, putWebuiPage, } from 'api/pages'; import { getStatusMap, @@ -33,7 +33,6 @@ import { getDefaultLanguage } from 'state/languages/selectors'; import { APP_TOUR_CANCELLED, APP_TOUR_STARTED, APP_TOUR_HOMEPAGE_CODEREF } from 'state/app-tour/const'; import { setExistingPages } from 'state/app-tour/actions'; import { getAppTourProgress } from 'state/app-tour/selectors'; -import { NEXT_PAGE_TEMPLATE_CODE } from 'ui/pages/common/const'; import getRuntimeEnv from 'helpers/getRuntimeEnv'; @@ -204,7 +203,7 @@ export const fetchViewPages = () => dispatch => new Promise((resolve) => { export const sendDeletePage = (page, successRedirect = true) => async (dispatch) => { try { let response = null; - if (WEBUI_ENABLED && page.pageModel === NEXT_PAGE_TEMPLATE_CODE) { + if (WEBUI_ENABLED) { response = await deleteWebuiPage(page); } else { response = await deletePage(page); @@ -212,12 +211,14 @@ export const sendDeletePage = (page, successRedirect = true) => async (dispatch) const json = await response.json(); if (response && response.ok) { dispatch(removePage(page)); + dispatch(addToast({ id: 'app.deleted', values: { type: 'page', code: page.code } }, TOAST_SUCCESS)); if (page.tourProgress === APP_TOUR_CANCELLED) return; if (page.tourProgress !== APP_TOUR_STARTED && successRedirect) { history.push(ROUTE_PAGE_TREE); } } else if (json && json.errors) { dispatch(addErrors(json.errors.map(e => e.message))); + json.errors.forEach(err => dispatch(addToast(err.message, TOAST_ERROR))); } } catch (e) { // do nothing @@ -329,7 +330,7 @@ export const sendPostPage = pageData => dispatch => new Promise(async (resolve) const postPageCall = SEO_ENABLED ? postPageSEO : postPage; let response = { json: () => {} }; let json = { errors: [] }; - if (WEBUI_ENABLED && pageData.pageModel === NEXT_PAGE_TEMPLATE_CODE) { + if (WEBUI_ENABLED) { response = await postWebuiPage({ ...pageData, ...seoPayload, @@ -475,7 +476,8 @@ export const sendPutPage = pageData => dispatch => useExtraTitles: seo, }, } : {}; - const response = await putPageFunc({ + const putApiCall = WEBUI_ENABLED ? putWebuiPage : putPageFunc; + const response = await putApiCall({ ...pageData, ...seoPayload, }); @@ -561,7 +563,7 @@ const putSelectedPageStatus = status => (dispatch, getState) => status: status === PAGE_STATUS_DRAFT ? PAGE_STATUS_UNPUBLISHED : status, }; dispatch(setPageLoading(page.code)); - const pageStatusApiCall = WEBUI_ENABLED && page.pageModel === NEXT_PAGE_TEMPLATE_CODE ? + const pageStatusApiCall = WEBUI_ENABLED ? putWebuiPageStatus : putPageStatus; pageStatusApiCall(page.code, status).then((response) => { if (response.ok) { diff --git a/src/ui/page-templates/list/PageTemplateListMenuActions.js b/src/ui/page-templates/list/PageTemplateListMenuActions.js index 9374afd2b..4e38d2d86 100644 --- a/src/ui/page-templates/list/PageTemplateListMenuActions.js +++ b/src/ui/page-templates/list/PageTemplateListMenuActions.js @@ -10,10 +10,8 @@ import { ROUTE_PAGE_TEMPLATE_CLONE, ROUTE_PAGE_TEMPLATE_DETAIL, } from 'app-init/router'; -import { NEXT_PAGE_TEMPLATE_CODE } from 'ui/pages/common/const'; - -const PageTemplateListMenuActions = ({ onClickDelete, code }) => ( +const PageTemplateListMenuActions = ({ onClickDelete, code, locked }) => ( ( { - code !== NEXT_PAGE_TEMPLATE_CODE && ( + !locked && ( ( PageTemplateListMenuActions.propTypes = { onClickDelete: PropTypes.func, code: PropTypes.string.isRequired, + locked: PropTypes.bool.isRequired, }; PageTemplateListMenuActions.defaultProps = { diff --git a/src/ui/page-templates/list/PageTemplateListTable.js b/src/ui/page-templates/list/PageTemplateListTable.js index 3cc14c209..c1ab470f5 100644 --- a/src/ui/page-templates/list/PageTemplateListTable.js +++ b/src/ui/page-templates/list/PageTemplateListTable.js @@ -81,6 +81,7 @@ class PageTemplateListTable extends Component { Cell: ({ values }) => ( removePageTemplate(values.code)} /> ), diff --git a/src/ui/pages/common/PageForm.js b/src/ui/pages/common/PageForm.js index 27e05e056..2c987d7fa 100644 --- a/src/ui/pages/common/PageForm.js +++ b/src/ui/pages/common/PageForm.js @@ -19,10 +19,6 @@ import SeoInfo from 'ui/pages/common/SeoInfo'; import FindTemplateModalContainer from 'ui/pages/common/FindTemplateModalContainer'; import { APP_TOUR_STARTED } from 'state/app-tour/const'; import { complementTitlesForActiveLanguages } from 'ui/pages/add/PagesAddFormContainer'; -import { NEXT_PAGE_TEMPLATE_CODE } from 'ui/pages/common/const'; -import getRuntimeEnv from 'helpers/getRuntimeEnv'; - -const { WEBUI_ENABLED } = getRuntimeEnv(); const maxLength30 = maxLength(30); const maxLength70 = maxLength(70); @@ -55,7 +51,7 @@ export class PageFormBody extends Component { intl, handleSubmit, invalid, submitting, groups, allGroups, pageTemplates, contentTypes, charsets, mode, onChangeDefaultTitle, parentCode, parentTitle, languages, pageCode, seoMode, onFindTemplateClick, appTourProgress, onChangePageTemplate, - onChangeOwnerGroup, readOnly, stayOnSave, form, editingPageTemplateCode, + onChangeOwnerGroup, readOnly, stayOnSave, form, } = this.props; let { pages } = this.props; if (pages && pages.length > 0) { @@ -64,18 +60,11 @@ export class PageFormBody extends Component { const isEditMode = mode === 'edit'; const isCloneMode = mode === 'clone'; - const pageTemplateDisabled = appTourProgress === APP_TOUR_STARTED || - (WEBUI_ENABLED && (isEditMode || isCloneMode) && - editingPageTemplateCode === NEXT_PAGE_TEMPLATE_CODE); + const pageTemplateDisabled = appTourProgress === APP_TOUR_STARTED; const pageTemplatesWithEmpty = [{ code: '', descr: intl.formatMessage(msgs.chooseAnOption) }].concat(pageTemplates); - const filteredPageTemplates = (isEditMode || isCloneMode) && - editingPageTemplateCode !== NEXT_PAGE_TEMPLATE_CODE ? - pageTemplatesWithEmpty.filter(pT => pT.code !== NEXT_PAGE_TEMPLATE_CODE) : - pageTemplatesWithEmpty; - const parentPageComponent = parentCode ? {parentTitle} : ( @@ -185,7 +174,7 @@ export class PageFormBody extends Component { /> } onChange={e => onChangePageTemplate(e.target.value, appTourProgress)} - options={filteredPageTemplates} + options={pageTemplatesWithEmpty} optionValue="code" optionDisplayName="descr" disabled={readOnly || pageTemplateDisabled} @@ -445,7 +434,6 @@ PageFormBody.propTypes = { onChangeOwnerGroup: PropTypes.func, readOnly: PropTypes.bool, stayOnSave: PropTypes.bool, - editingPageTemplateCode: PropTypes.string, }; PageFormBody.defaultProps = { @@ -465,7 +453,6 @@ PageFormBody.defaultProps = { onChangeOwnerGroup: () => {}, readOnly: false, stayOnSave: false, - editingPageTemplateCode: '', }; const PageForm = reduxForm({ diff --git a/src/ui/pages/common/PageTreeActionMenu.js b/src/ui/pages/common/PageTreeActionMenu.js index 43468476f..75174ecfb 100644 --- a/src/ui/pages/common/PageTreeActionMenu.js +++ b/src/ui/pages/common/PageTreeActionMenu.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import { DropdownKebab, MenuItem } from 'patternfly-react'; import { PAGE_STATUS_PUBLISHED, PAGE_STATUS_UNPUBLISHED } from 'state/pages/const'; +import { NEXT_PAGE_TEMPLATE_CODE } from 'ui/pages/common/const'; class PageTreeActionMenu extends Component { constructor(props) { @@ -106,7 +107,7 @@ class PageTreeActionMenu extends Component { )} - {onClickConfigure && ( + {onClickConfigure && page.pageModel !== NEXT_PAGE_TEMPLATE_CODE && ( )} {renderDeleteItem()} - - - + { + page.pageModel !== NEXT_PAGE_TEMPLATE_CODE && ( + + + + ) + } {viewPublishedPage} diff --git a/src/ui/pages/edit/PagesEditFormContainer.js b/src/ui/pages/edit/PagesEditFormContainer.js index 5c5980980..a5cf3104e 100644 --- a/src/ui/pages/edit/PagesEditFormContainer.js +++ b/src/ui/pages/edit/PagesEditFormContainer.js @@ -14,7 +14,6 @@ import { fetchPageTemplates } from 'state/page-templates/actions'; import { history, ROUTE_PAGE_TREE, ROUTE_PAGE_CONFIG } from 'app-init/router'; import { fetchLanguages } from 'state/languages/actions'; import { setVisibleModal } from 'state/modal/actions'; -import { formValueSelector } from 'redux-form'; export const FORM_ID = 'pageEdit'; @@ -31,7 +30,6 @@ export const mapStateToProps = (state, { match: { params } }) => ({ pageCode: params.pageCode, form: FORM_ID, keepDirtyOnReinitialize: true, - editingPageTemplateCode: formValueSelector(FORM_ID)(state, 'pageModel'), }); diff --git a/test/api/pages.test.js b/test/api/pages.test.js index 0fdd0c79d..a6010db77 100644 --- a/test/api/pages.test.js +++ b/test/api/pages.test.js @@ -3,7 +3,7 @@ import { getPage, getPageChildren, setPagePosition, postPage, putPage, patchPage, deletePage, getSearchPages, getPageSettings, getFreePages, getPageConfig, deletePageWidget, putPageWidget, getReferencesPage, restorePageConfig, applyDefaultPageConfig, putPageSettings, deleteWebuiPage, - postWebuiPage, putWebuiPageStatus, postWebuiClonePage, + postWebuiPage, putWebuiPageStatus, postWebuiClonePage, putWebuiPage, } from 'api/pages'; import { CONTACTS_PAYLOAD, FREE_PAGES_PAYLOAD, PAGE_SETTINGS_PAYLOAD, SEARCH_PAGES } from 'test/mocks/pages'; @@ -391,4 +391,21 @@ describe('api/pages', () => { })); }); }); + + describe('putWebuiPage', () => { + it('returns a promise', () => { + expect(putWebuiPage(CONTACTS_PAYLOAD)).toBeInstanceOf(Promise); + }); + + it('makes the correct request', () => { + putWebuiPage(CONTACTS_PAYLOAD); + expect(makeRequest).toHaveBeenCalledWith(expect.objectContaining({ + uri: `/api/pages/${CONTACTS_PAYLOAD.code}`, + body: CONTACTS_PAYLOAD, + method: METHODS.PUT, + errors: expect.any(Function), + useAuthentication: true, + })); + }); + }); }); From 83a5dd80da83e2e184774a73200b9800358ef651 Mon Sep 17 00:00:00 2001 From: Walter Caffiero Date: Tue, 28 Dec 2021 09:47:01 +0100 Subject: [PATCH 03/12] ENG-3071 Pipelines and Epic Branches for webui --- .github/workflows/ga-publication.yml | 6 ++- .github/workflows/post-merge.yml | 14 ++++--- .github/workflows/pr.yml | 55 +++++++++++++++++++--------- .github/workflows/publication.yml | 40 +++++++++++++++----- 4 files changed, 82 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ga-publication.yml b/.github/workflows/ga-publication.yml index b7c63f487..3c6078612 100644 --- a/.github/workflows/ga-publication.yml +++ b/.github/workflows/ga-publication.yml @@ -6,17 +6,21 @@ on: - created env: - ENTANDO_OPT_USE_PPL_TAG: "v1.1.0" + ENTANDO_OPT_USE_PPL_TAG: "v1.2.0" ENTANDO_OPT_FEATURES: "${{ secrets.ENTANDO_OPT_FEATURES }}" ENTANDO_OPT_GLOBAL_FEATURES: "${{ secrets.ENTANDO_OPT_GLOBAL_FEATURES }}" ENTANDO_OPT_LOG_LEVEL: "${{ secrets.ENTANDO_OPT_LOG_LEVEL }}" ENTANDO_OPT_REPO_BOM_URL: "${{ secrets.ENTANDO_OPT_REPO_BOM_URL }}" + ENTANDO_OPT_CUSTOM_ENV: "${{ secrets.ENTANDO_OPT_CUSTOM_ENV }}" PPL_CONTEXT: ${{ toJson(github) }} GIT_USER_NAME: "${{ secrets.GIT_USER_NAME }}" GIT_USER_EMAIL: "${{ secrets.GIT_USER_EMAIL }}" LOCAL_CLONE_DIR: "local-checkout" jobs: + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + # GA PUBLICATION ga-publish: env: ENTANDO_OPT_MAVEN_REPO_GA: ${{ secrets.ENTANDO_OPT_MAVEN_REPO_GA }} diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index 98f0f8284..fb130f55a 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -4,9 +4,11 @@ on: push: branches: - develop + - epic/* + - release/* env: - ENTANDO_OPT_USE_PPL_TAG: "v1.1.0" + ENTANDO_OPT_USE_PPL_TAG: "v1.2.0" ENTANDO_OPT_FEATURES: "${{ secrets.ENTANDO_OPT_FEATURES }}" ENTANDO_OPT_GLOBAL_FEATURES: "${{ secrets.ENTANDO_OPT_GLOBAL_FEATURES }}" ENTANDO_OPT_LOG_LEVEL: "${{ secrets.ENTANDO_OPT_LOG_LEVEL }}" @@ -19,11 +21,13 @@ env: jobs: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - # TAG - add-release-tag: + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + # SNAPSHOT TAG + + add-snapshot-tag: runs-on: ubuntu-latest steps: - - name: "ADD RELEASE TAG" + - name: "ADD SNAPSHOT TAG" run: | ${{ secrets.ENTANDO_OPT_PPL_INSTALL_CMD }} @@ -33,5 +37,5 @@ jobs: --lcd "$LOCAL_CLONE_DIR" \ --token "${{ secrets.ENTANDO_BOT_TOKEN }}" \ .. release tag-snapshot-version \ - --id "TAG-RELEASE" \ + --id "TAG-SNAPSHOT" \ --lcd "$LOCAL_CLONE_DIR" diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index d83214bec..850dac55f 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -6,15 +6,23 @@ on: - opened - synchronize - reopened - branches: + branches: - develop + - epic/* + - release/* env: - ENTANDO_OPT_USE_PPL_TAG: "v1.1.0" + ENTANDO_OPT_USE_PPL_TAG: "v1.2.0" ENTANDO_OPT_FEATURES: "${{ secrets.ENTANDO_OPT_FEATURES }}" ENTANDO_OPT_GLOBAL_FEATURES: "${{ secrets.ENTANDO_OPT_GLOBAL_FEATURES }}" ENTANDO_OPT_LOG_LEVEL: "${{ secrets.ENTANDO_OPT_LOG_LEVEL }}" ENTANDO_OPT_REPO_BOM_URL: "${{ secrets.ENTANDO_OPT_REPO_BOM_URL }}" + ENTANDO_OPT_CUSTOM_ENV: "${{ secrets.ENTANDO_OPT_CUSTOM_ENV }}" + ENTANDO_OPT_OKD_LOGIN: "${{ secrets.ENTANDO_OPT_OKD_LOGIN }}" + ENTANDO_OPT_IMAGE_REGISTRY_OVERRIDE: "${{ secrets.ENTANDO_OPT_IMAGE_REGISTRY_OVERRIDE }}" + ENTANDO_OPT_DOCKER_ORG: "${{ secrets.ENTANDO_OPT_DOCKER_ORG }}" + ENTANDO_OPT_TEST_NAMESPACE: "${{ secrets.ENTANDO_OPT_TEST_NAMESPACE }}" + ENTANDO_OPT_HELM_CLI_URL: "${{ secrets.ENTANDO_OPT_HELM_CLI_URL }}" PPL_CONTEXT: ${{ toJson(github) }} GIT_USER_NAME: "${{ secrets.GIT_USER_NAME }}" GIT_USER_EMAIL: "${{ secrets.GIT_USER_EMAIL }}" @@ -40,19 +48,13 @@ jobs: .. status-report \ .. @checkout-branch pr --lcd "$LOCAL_CLONE_DIR" \ .. @setup-feature-flags "PR_PREFLIGHT_CHECKS" "BOM_CHECK" "BOM" \ - .. @setup-features-list "SCAN_MATRIX" --prefix "SCAN-NPM-" \ + .. @setup-features-list "SCAN_MATRIX" --prefix "MTX-NPM-,MTX-SCAN-" \ ; - name: "PR preflight checks" if: steps.START.outputs.PR_PREFLIGHT_CHECKS != 'false' id: pr-preflight-checks run: | ~/ppl-run pr-preflight-checks --lcd "$LOCAL_CLONE_DIR" - # BOM - - name: "entando-core-bom check" - if: steps.START.outputs.BOM_CHECK != 'false' && steps.START.outputs.BOM == 'true' - id: pr-bom-check - run: | - ~/ppl-run @pr-labels add "prepared" --id "ADD-LABEL-PREPARED" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -61,6 +63,13 @@ jobs: full-build: needs: [ 'prepare' ] runs-on: ubuntu-latest + env: + ENTANDO_BOT_TOKEN: ${{ secrets.ENTANDO_BOT_TOKEN }} + ENTANDO_OPT_OKD_LOGIN_URL: "${{ secrets.ENTANDO_OPT_OKD_LOGIN_URL }}" + ENTANDO_OPT_OKD_LOGIN_TOKEN: "${{ secrets.ENTANDO_OPT_OKD_LOGIN_TOKEN }}" + ENTANDO_OPT_OKD_LOGIN_NAMESPACE: "${{ secrets.ENTANDO_OPT_OKD_LOGIN_NAMESPACE }}" + ENTANDO_OPT_OKD_LOGIN_INSECURE: "${{ secrets.ENTANDO_OPT_OKD_LOGIN_INSECURE }}" + ENTANDO_OPT_OKD_CLI_URL: "${{ secrets.ENTANDO_OPT_OKD_CLI_URL }}" steps: #~ CHECKOUT - name: "CHECKOUT" @@ -68,7 +77,7 @@ jobs: ${{ secrets.ENTANDO_OPT_PPL_INSTALL_CMD }} ~/ppl-run checkout-branch pr \ --lcd "$LOCAL_CLONE_DIR" \ - --token "${{ secrets.ENTANDO_BOT_TOKEN }}" \ + --token "$ENTANDO_BOT_TOKEN" \ ; #~ NODE - uses: actions/setup-node@v2 @@ -81,6 +90,7 @@ jobs: with: path: ~/.npm key: ${{ runner.os }}-npm + restore-keys: ${{ runner.os }}-npm #~ BUILD CACHE - name: "Cache Build Dir" id: build-cache @@ -90,18 +100,17 @@ jobs: key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} #~ BUILD - name: "FULL BUILD" + env: + ENTANDO_OPT_SONAR_PROJECT_KEY: "${{ secrets.ENTANDO_OPT_SONAR_PROJECT_KEY }}" + SONAR_TOKEN: "${{ secrets.SONAR_TOKEN }}" + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" run: | - ~/ppl-run \ - .. generic FULL-BUILD --lcd "$LOCAL_CLONE_DIR" \ - .. release tag-snapshot-version --lcd "$LOCAL_CLONE_DIR" \ - ; + ~/ppl-run generic FULL-BUILD --lcd "$LOCAL_CLONE_DIR" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # SCANS scans: - env: - CI: true needs: [ 'prepare', 'full-build' ] runs-on: ubuntu-latest if: ${{ needs.prepare.outputs.SCAN_MATRIX != '' }} @@ -118,7 +127,8 @@ jobs: ${{ secrets.ENTANDO_OPT_PPL_INSTALL_CMD }} ~/ppl-run checkout-branch pr --lcd "$LOCAL_CLONE_DIR" #~ NODE - - uses: actions/setup-node@v2 + - name: "Set up Node 14" + uses: actions/setup-node@v2 with: node-version: 14.x #~ NPM CACHE @@ -128,6 +138,10 @@ jobs: with: path: ~/.npm key: ${{ runner.os }}-npm + restore-keys: | + ${{ runner.os }}-npm-matrix-${{ matrix.scan-type }} + ${{ runner.os }}-npm-matrix- + ${{ runner.os }}-npm- #~ BUILD CACHE - name: "Cache Build Dir" id: build-cache @@ -136,7 +150,12 @@ jobs: path: "${{ env.LOCAL_CLONE_DIR }}/build/" key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} #~ SCAN - - name: "Run the Scan" + - name: "Run the matrix step ${{ matrix.scan-type }}" run: | SCAN_TYPE="${{ matrix.scan-type }}" + case "$SCAN_TYPE" in + MTX-SCAN-SNYK) + export SNYK_TOKEN="${{ secrets.SNYK_TOKEN }}" + ;; + esac ~/ppl-run generic "$SCAN_TYPE" mvn --id "$SCAN_TYPE" --lcd "$LOCAL_CLONE_DIR" diff --git a/.github/workflows/publication.yml b/.github/workflows/publication.yml index b260788c2..588bfd1fd 100644 --- a/.github/workflows/publication.yml +++ b/.github/workflows/publication.yml @@ -6,11 +6,12 @@ on: - 'v*' env: - ENTANDO_OPT_USE_PPL_TAG: "v1.1.0" + ENTANDO_OPT_USE_PPL_TAG: "v1.2.0" ENTANDO_OPT_FEATURES: "${{ secrets.ENTANDO_OPT_FEATURES }}" ENTANDO_OPT_GLOBAL_FEATURES: "${{ secrets.ENTANDO_OPT_GLOBAL_FEATURES }}" ENTANDO_OPT_LOG_LEVEL: "${{ secrets.ENTANDO_OPT_LOG_LEVEL }}" ENTANDO_OPT_REPO_BOM_URL: "${{ secrets.ENTANDO_OPT_REPO_BOM_URL }}" + ENTANDO_OPT_CUSTOM_ENV: "${{ secrets.ENTANDO_OPT_CUSTOM_ENV }}" PPL_CONTEXT: ${{ toJson(github) }} GIT_USER_NAME: "${{ secrets.GIT_USER_NAME }}" GIT_USER_EMAIL: "${{ secrets.GIT_USER_EMAIL }}" @@ -18,26 +19,35 @@ env: jobs: + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + # INTERNAL PUBLICATION internal-publication: + env: + ENTANDO_BOT_TOKEN: ${{ secrets.ENTANDO_BOT_TOKEN }} runs-on: ubuntu-latest steps: - name: "PR PIPELINE START" id: START run: | ${{ secrets.ENTANDO_OPT_PPL_INSTALL_CMD }} - ~/ppl-run status-report \ + ~/ppl-run \ + .. status-report \ .. @setup-feature-flags "PR_FORMAT_CHECK" "BOM_CHECK" "BOM" \ - .. @setup-features-list "SCAN_MATRIX" true SONAR_SCAN OWASP_SCAN SNYK_SCAN \ ; #~ CHECKOUT - - name: "Checkout" + - name: "CHECKOUT" + id: CHECKOUT run: | - ~/ppl-run checkout-branch base \ - --id "CHECKOUT FOR NEXUS PUBLICATION" \ - --lcd "$LOCAL_CLONE_DIR" \ + ~/ppl-run \ + .. checkout-branch --id "CHECKOUT FOR NEXUS PUBLICATION" \ + --lcd "$LOCAL_CLONE_DIR" \ + --token "$ENTANDO_BOT_TOKEN" \ + .. pr-preflight-checks --only flags --lcd "$LOCAL_CLONE_DIR" \ ; #~ NODE - - uses: actions/setup-node@v2 + - name: "Set up Node 14" + uses: actions/setup-node@v2 with: node-version: 14.x #~ NPM CACHE @@ -52,7 +62,7 @@ jobs: id: build-cache uses: actions/cache@v2 with: - path: "${{ env.LOCAL_CLONE_DIR }}/build/" + path: "${{ env.LOCAL_CLONE_DIR }}/build/" key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} #~ PUBLISH PACKAGE - name: "Publish package" @@ -60,6 +70,18 @@ jobs: ~/ppl-run generic PUBLISH \ --id "PUBLICATION" \ --lcd "$LOCAL_CLONE_DIR" + env: + NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} + NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} + #~ UPDATE THE BOM (if required) + - name: "BOM Update" + if: steps.CHECKOUT.outputs.BOM_UPDATE_FLAG == 'true' && steps.START.outputs.BOM == 'true' + run: | + ~/ppl-run bom update-bom \ + --id "UPDATE-BOM" \ + --lcd "$LOCAL_CLONE_DIR" \ + --token "$ENTANDO_BOT_TOKEN" \ + ; #~ PUBLISH TO DOCKER IMAGE - name: "Publish docker" env: From 173981082fe1ae5dde62d7e60183cc9292221fc7 Mon Sep 17 00:00:00 2001 From: Walter Caffiero Date: Tue, 28 Dec 2021 10:55:06 +0100 Subject: [PATCH 04/12] ENG-3071 fix post merge --- .github/workflows/post-merge.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index fb130f55a..c2386cee4 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -24,7 +24,7 @@ jobs: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # SNAPSHOT TAG - add-snapshot-tag: + add-version-tag: runs-on: ubuntu-latest steps: - name: "ADD SNAPSHOT TAG" @@ -36,6 +36,6 @@ jobs: --id "CHECKOUT-BASE" \ --lcd "$LOCAL_CLONE_DIR" \ --token "${{ secrets.ENTANDO_BOT_TOKEN }}" \ - .. release tag-snapshot-version \ - --id "TAG-SNAPSHOT" \ + .. publication tag-git-version \ + --id "TAG-VERSION" \ --lcd "$LOCAL_CLONE_DIR" From 6ab1df9981018f9a2a944f822415e30bddce0c65 Mon Sep 17 00:00:00 2001 From: Irakli Chalagashvili Date: Mon, 27 Dec 2021 22:20:07 +0400 Subject: [PATCH 05/12] ENG-3043 open vscode --- config/env.js | 1 + src/helpers/getRuntimeEnv.js | 1 + src/ui/pages/common/PageTree.js | 12 ++++++------ src/ui/pages/common/PageTreeActionMenu.js | 18 ++++++++++++++---- src/ui/pages/common/const.js | 2 +- test/test/mocks/pages.js | 1 + 6 files changed, 24 insertions(+), 11 deletions(-) diff --git a/config/env.js b/config/env.js index 4147e8170..968ab48c6 100644 --- a/config/env.js +++ b/config/env.js @@ -63,6 +63,7 @@ const RUNTIME_OVERRIDABLE_VARS = [ 'KEYCLOAK_JSON', 'WEBUI_ENABLED', 'WEBUI_APP_MANAGEMENT_URL', + 'WEBUI_APP_URL', ]; function getClientEnvironment(publicUrl) { diff --git a/src/helpers/getRuntimeEnv.js b/src/helpers/getRuntimeEnv.js index 61fbd89f9..ce1d72503 100644 --- a/src/helpers/getRuntimeEnv.js +++ b/src/helpers/getRuntimeEnv.js @@ -35,4 +35,5 @@ export default () => ({ KEYCLOAK_JSON: getEnvVar('KEYCLOAK_JSON') || `${validateDomain(getEnvVar('DOMAIN'))}/keycloak.json`, WEBUI_ENABLED: getBooleanEnvVar('WEBUI_ENABLED'), WEBUI_APP_MANAGEMENT_URL: getEnvVar('WEBUI_APP_MANAGEMENT_URL'), + WEBUI_APP_URL: getEnvVar('WEBUI_APP_URL'), }); diff --git a/src/ui/pages/common/PageTree.js b/src/ui/pages/common/PageTree.js index 36af1775c..f818d908c 100644 --- a/src/ui/pages/common/PageTree.js +++ b/src/ui/pages/common/PageTree.js @@ -17,7 +17,7 @@ import UnpublishPageModalContainer from 'ui/pages/common/UnpublishPageModalConta import PageListSearchTable from 'ui/pages/list/PageListSearchTable'; import MovePageModalContainer from 'ui/pages/common/MovePageModalContainer'; import { PAGE_MOVEMENT_OPTIONS } from 'state/pages/const'; -import { NEXT_PAGE_TEMPLATE_CODE } from 'ui/pages/common/const'; +import { NEXT_PAGE_TYPE } from 'ui/pages/common/const'; import getRuntimeEnv from 'helpers/getRuntimeEnv'; @@ -38,7 +38,7 @@ class PageTree extends Component { componentDidMount() { const { columnOrder, onSetColumnOrder } = this.props; if (!columnOrder.length) { - onSetColumnOrder(WEBUI_ENABLED ? ['title', 'pageModel', 'status', 'displayedInMenu'] : + onSetColumnOrder(WEBUI_ENABLED ? ['title', 'type', 'status', 'displayedInMenu'] : ['title', 'status', 'displayedInMenu']); } } @@ -115,14 +115,14 @@ class PageTree extends Component { }, }, ...(WEBUI_ENABLED && { - pageModel: { + type: { Header: , attributes: { className: 'text-center PageTree__thead', style: { width: '5%', verticalAlign: 'middle' }, }, Cell: ({ value }) => ( - + ), cellAttributes: { className: 'text-center', @@ -251,7 +251,7 @@ PageTree.propTypes = { code: PropTypes.string.isRequired, status: PropTypes.string.isRequired, displayedInMenu: PropTypes.bool.isRequired, - pageModel: PropTypes.string.isRequired, + type: PropTypes.string.isRequired, title: PropTypes.string.isRequired, depth: PropTypes.number.isRequired, expanded: PropTypes.bool.isRequired, @@ -289,7 +289,7 @@ PageTree.defaultProps = { onExpandAll: () => {}, onCollapseAll: () => {}, onSetColumnOrder: () => {}, - columnOrder: WEBUI_ENABLED ? ['title', 'pageModel', 'status', 'displayedInMenu'] : + columnOrder: WEBUI_ENABLED ? ['title', 'type', 'status', 'displayedInMenu'] : ['title', 'status', 'displayedInMenu'], }; diff --git a/src/ui/pages/common/PageTreeActionMenu.js b/src/ui/pages/common/PageTreeActionMenu.js index 75174ecfb..a7f824e05 100644 --- a/src/ui/pages/common/PageTreeActionMenu.js +++ b/src/ui/pages/common/PageTreeActionMenu.js @@ -3,7 +3,15 @@ import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import { DropdownKebab, MenuItem } from 'patternfly-react'; import { PAGE_STATUS_PUBLISHED, PAGE_STATUS_UNPUBLISHED } from 'state/pages/const'; -import { NEXT_PAGE_TEMPLATE_CODE } from 'ui/pages/common/const'; +import { NEXT_PAGE_TYPE } from 'ui/pages/common/const'; +import getRuntimeEnv from 'helpers/getRuntimeEnv'; + +const { WEBUI_APP_URL } = getRuntimeEnv(); + +const openInNewTab = (url) => { + const newWindow = window.open(url, '_blank', 'noopener,noreferrer'); + if (newWindow) newWindow.opener = null; +}; class PageTreeActionMenu extends Component { constructor(props) { @@ -90,6 +98,7 @@ class PageTreeActionMenu extends Component { ); + const handleDesignNextPage = () => openInNewTab(WEBUI_APP_URL); return (
e.stopPropagation()} role="none" data-testid={`${page.code}-actions`}> @@ -107,10 +116,11 @@ class PageTreeActionMenu extends Component { )} - {onClickConfigure && page.pageModel !== NEXT_PAGE_TEMPLATE_CODE && ( + {onClickConfigure && ( @@ -132,7 +142,7 @@ class PageTreeActionMenu extends Component { )} {renderDeleteItem()} { - page.pageModel !== NEXT_PAGE_TEMPLATE_CODE && ( + page.type !== NEXT_PAGE_TYPE && ( Date: Tue, 28 Dec 2021 21:35:16 +0400 Subject: [PATCH 06/12] ENG-3043 extract tab open to helper functions --- src/helpers/urlUtils.js | 7 ++++++- src/ui/assets/AssetsList.js | 3 ++- src/ui/assets/AssetsListGridView.js | 3 ++- src/ui/pages/common/FindTemplateModal.js | 3 ++- src/ui/pages/common/PageTreeActionMenu.js | 6 +----- src/ui/pages/common/PageTreeContainer.js | 5 +++-- src/ui/pages/config/ContentPagesContainer.js | 5 +++-- src/ui/pages/config/PageConfigPage.js | 3 ++- 8 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/helpers/urlUtils.js b/src/helpers/urlUtils.js index 0ec02fddb..3497fa373 100644 --- a/src/helpers/urlUtils.js +++ b/src/helpers/urlUtils.js @@ -1,3 +1,8 @@ import { get } from 'lodash'; -// eslint-disable-next-line import/prefer-default-export + export const adminConsoleUrl = url => `${get(process.env, 'REACT_APP_DOMAIN', '')}/${url}`; + +export const openInNewTab = (url) => { + const newWindow = window.open(url, '_blank', 'noopener,noreferrer'); + if (newWindow) newWindow.opener = null; +}; diff --git a/src/ui/assets/AssetsList.js b/src/ui/assets/AssetsList.js index 7da2936f2..cc168b4f4 100644 --- a/src/ui/assets/AssetsList.js +++ b/src/ui/assets/AssetsList.js @@ -27,6 +27,7 @@ import { SORTABLE_COLUMNS, ASSET_FILETYPES, } from 'state/assets/const'; +import { openInNewTab } from 'helpers/urlUtils'; class AssetsList extends Component { constructor(props) { @@ -281,7 +282,7 @@ class AssetsList extends Component { onDuplicateClicked(asset)}> - window.open(asset.downloadUrl)}> + openInNewTab(asset.downloadUrl)}> onClickDelete(asset)}> diff --git a/src/ui/assets/AssetsListGridView.js b/src/ui/assets/AssetsListGridView.js index 64f4a2137..92e498ce3 100644 --- a/src/ui/assets/AssetsListGridView.js +++ b/src/ui/assets/AssetsListGridView.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import { DropdownKebab, MenuItem, Button } from 'patternfly-react'; +import { openInNewTab } from 'helpers/urlUtils'; const AssetsListGridView = ({ assets, @@ -25,7 +26,7 @@ const AssetsListGridView = ({ const onEditClickHandle = () => onEditClicked(asset); const onClickDeleteHandle = () => onClickDelete(asset); const onDuplicateClickHandle = () => onDuplicateClicked(asset); - const onDownloadHandle = () => window.open(asset.downloadUrl); + const onDownloadHandle = () => openInNewTab(asset.downloadUrl); const onClickSelectHandle = () => onItemSelected(asset); return (
diff --git a/src/ui/pages/common/FindTemplateModal.js b/src/ui/pages/common/FindTemplateModal.js index 2d400f3a5..489adc66b 100644 --- a/src/ui/pages/common/FindTemplateModal.js +++ b/src/ui/pages/common/FindTemplateModal.js @@ -6,6 +6,7 @@ import { Modal, Col, Row, Spinner, DropdownKebab, MenuItem, Button } from 'patte import GenericModalContainer from 'ui/common/modal/GenericModalContainer'; import { ROUTE_PAGE_TEMPLATE_DETAIL } from 'app-init/router'; import { TEMPLATE_THUMBNAIL } from 'ui/pages/common/const'; +import { openInNewTab } from 'helpers/urlUtils'; export const MODAL_ID = 'FindTemplateModal'; @@ -61,7 +62,7 @@ const FindTemplateModal = ({ onClick={() => { const templatePath = ROUTE_PAGE_TEMPLATE_DETAIL.replace(':pageTemplateCode', code); const link = `${global.location.href.split('/page')[0]}${templatePath}`; - window.open(link); + openInNewTab(link); }} > diff --git a/src/ui/pages/common/PageTreeActionMenu.js b/src/ui/pages/common/PageTreeActionMenu.js index a7f824e05..0558c0850 100644 --- a/src/ui/pages/common/PageTreeActionMenu.js +++ b/src/ui/pages/common/PageTreeActionMenu.js @@ -5,14 +5,10 @@ import { DropdownKebab, MenuItem } from 'patternfly-react'; import { PAGE_STATUS_PUBLISHED, PAGE_STATUS_UNPUBLISHED } from 'state/pages/const'; import { NEXT_PAGE_TYPE } from 'ui/pages/common/const'; import getRuntimeEnv from 'helpers/getRuntimeEnv'; +import { openInNewTab } from 'helpers/urlUtils'; const { WEBUI_APP_URL } = getRuntimeEnv(); -const openInNewTab = (url) => { - const newWindow = window.open(url, '_blank', 'noopener,noreferrer'); - if (newWindow) newWindow.opener = null; -}; - class PageTreeActionMenu extends Component { constructor(props) { super(props); diff --git a/src/ui/pages/common/PageTreeContainer.js b/src/ui/pages/common/PageTreeContainer.js index 7e78203b3..37a026647 100644 --- a/src/ui/pages/common/PageTreeContainer.js +++ b/src/ui/pages/common/PageTreeContainer.js @@ -34,6 +34,7 @@ import { PAGE_INIT_VALUES } from 'ui/pages/common/const'; import { setAppTourLastStep } from 'state/app-tour/actions'; import { getDomain } from '@entando/apimanager'; import { PREVIEW_NAMESPACE } from 'ui/pages/config/const'; +import { openInNewTab } from 'helpers/urlUtils'; export const mapStateToProps = state => ({ locale: getLocale(state), @@ -89,10 +90,10 @@ export const mapDispatchToProps = (dispatch, ownProps) => ({ dispatch(clearSearchPage()); }, onClickViewPublishedPage: (page, domain, locale) => { - window.open(`${domain}/${locale}/${page.code}.page`, '_blank'); + openInNewTab(`${domain}/${locale}/${page.code}.page`); }, onClickPreview: (page, domain) => { - window.open(`${domain}/${PREVIEW_NAMESPACE}?pageCode=${page.code}&token=${page.token}`, '_blank'); + openInNewTab(`${domain}/${PREVIEW_NAMESPACE}?pageCode=${page.code}&token=${page.token}`); }, onDropPage: (sourcePageCode, targetPageCode, action) => { dispatch(setVisibleModal(MOVE_MODAL_ID)); diff --git a/src/ui/pages/config/ContentPagesContainer.js b/src/ui/pages/config/ContentPagesContainer.js index 71a4b1e2b..b5ebbe265 100644 --- a/src/ui/pages/config/ContentPagesContainer.js +++ b/src/ui/pages/config/ContentPagesContainer.js @@ -26,6 +26,7 @@ import { getUserPreferences } from 'state/user-preferences/selectors'; import { history, ROUTE_PAGE_CONFIG } from 'app-init/router'; import { getDomain } from '@entando/apimanager'; import { PREVIEW_NAMESPACE } from 'ui/pages/config/const'; +import { openInNewTab } from 'helpers/urlUtils'; export const mapStateToProps = state => ({ loading: getLoading(state).pageTree, @@ -72,10 +73,10 @@ export const mapDispatchToProps = dispatch => ({ dispatch(clearSearchPage()); }, onClickPreview: (page, domain) => { - window.open(`${domain}/${PREVIEW_NAMESPACE}?pageCode=${page.code}&token=${page.token}`, '_blank'); + openInNewTab(`${domain}/${PREVIEW_NAMESPACE}?pageCode=${page.code}&token=${page.token}`); }, onClickViewPublishedPage: (page, domain, locale) => { - window.open(`${domain}/${locale}/${page.code}.page`, '_blank'); + openInNewTab(`${domain}/${locale}/${page.code}.page`); }, onExpandAll: (currentPage) => { dispatch(fetchPageTreeAll()); diff --git a/src/ui/pages/config/PageConfigPage.js b/src/ui/pages/config/PageConfigPage.js index 9dfa42b5c..85b7aae44 100644 --- a/src/ui/pages/config/PageConfigPage.js +++ b/src/ui/pages/config/PageConfigPage.js @@ -15,6 +15,7 @@ import AppTourContainer from 'ui/app-tour/AppTourContainer'; import { APP_TOUR_STARTED } from 'state/app-tour/const'; import { PAGE_STATUS_PUBLISHED, PAGE_STATUS_UNPUBLISHED } from 'state/pages/const'; import PagesEditFormContainer from 'ui/pages/edit/PagesEditFormContainer'; +import { openInNewTab } from 'helpers/urlUtils'; const msgs = defineMessages({ appYes: { @@ -107,7 +108,7 @@ class PageConfigPage extends Component { openLinkPublishedPage() { if (this.props.pageStatus !== PAGE_STATUS_UNPUBLISHED) { - window.open(this.props.publishedPageUri, '_blank'); + openInNewTab(this.props.publishedPageUri); } } From a9153de780a8338d96419e9d71b24004d3a23555 Mon Sep 17 00:00:00 2001 From: Irakli Chalagashvili Date: Mon, 3 Jan 2022 17:27:24 +0400 Subject: [PATCH 07/12] webui/ENG-3073 open preview link --- src/ui/pages/common/PageTreeActionMenu.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ui/pages/common/PageTreeActionMenu.js b/src/ui/pages/common/PageTreeActionMenu.js index 0558c0850..c1de7735c 100644 --- a/src/ui/pages/common/PageTreeActionMenu.js +++ b/src/ui/pages/common/PageTreeActionMenu.js @@ -95,6 +95,7 @@ class PageTreeActionMenu extends Component { ); const handleDesignNextPage = () => openInNewTab(WEBUI_APP_URL); + const handlePreviewNextPage = () => openInNewTab(page.nextLink); return (
e.stopPropagation()} role="none" data-testid={`${page.code}-actions`}> @@ -138,14 +139,14 @@ class PageTreeActionMenu extends Component { )} {renderDeleteItem()} { - page.type !== NEXT_PAGE_TYPE && ( - - - - ) + + + + } {viewPublishedPage} From a7a9b8c468396b7c9b4f7247e1f4b4c9c0f2679f Mon Sep 17 00:00:00 2001 From: Irakli Chalagashvili Date: Thu, 13 Jan 2022 16:55:47 +0400 Subject: [PATCH 08/12] webui/ENG-3073 Fix url generation --- src/ui/pages/common/PageTreeActionMenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/pages/common/PageTreeActionMenu.js b/src/ui/pages/common/PageTreeActionMenu.js index c1de7735c..e7ed69df8 100644 --- a/src/ui/pages/common/PageTreeActionMenu.js +++ b/src/ui/pages/common/PageTreeActionMenu.js @@ -95,7 +95,7 @@ class PageTreeActionMenu extends Component { ); const handleDesignNextPage = () => openInNewTab(WEBUI_APP_URL); - const handlePreviewNextPage = () => openInNewTab(page.nextLink); + const handlePreviewNextPage = () => openInNewTab(`${WEBUI_APP_URL}/entando-de-app/en/${page.code}.page`); return (
e.stopPropagation()} role="none" data-testid={`${page.code}-actions`}> From 1d94e34b636462bc5f4e35e5281ff7418102872f Mon Sep 17 00:00:00 2001 From: Irakli Chalagashvili Date: Mon, 17 Jan 2022 17:49:59 +0400 Subject: [PATCH 09/12] webui/ENG-3042 fix vscode path --- config/env.js | 1 + src/helpers/getRuntimeEnv.js | 1 + src/ui/pages/common/PageTreeActionMenu.js | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config/env.js b/config/env.js index 968ab48c6..93e8648ef 100644 --- a/config/env.js +++ b/config/env.js @@ -64,6 +64,7 @@ const RUNTIME_OVERRIDABLE_VARS = [ 'WEBUI_ENABLED', 'WEBUI_APP_MANAGEMENT_URL', 'WEBUI_APP_URL', + 'WEBUI_DEV_WORKSPACE_URL', ]; function getClientEnvironment(publicUrl) { diff --git a/src/helpers/getRuntimeEnv.js b/src/helpers/getRuntimeEnv.js index ce1d72503..42331f1a9 100644 --- a/src/helpers/getRuntimeEnv.js +++ b/src/helpers/getRuntimeEnv.js @@ -36,4 +36,5 @@ export default () => ({ WEBUI_ENABLED: getBooleanEnvVar('WEBUI_ENABLED'), WEBUI_APP_MANAGEMENT_URL: getEnvVar('WEBUI_APP_MANAGEMENT_URL'), WEBUI_APP_URL: getEnvVar('WEBUI_APP_URL'), + WEBUI_DEV_WORKSPACE_URL: getEnvVar('WEBUI_DEV_WORKSPACE_URL'), }); diff --git a/src/ui/pages/common/PageTreeActionMenu.js b/src/ui/pages/common/PageTreeActionMenu.js index e7ed69df8..6dd09c21d 100644 --- a/src/ui/pages/common/PageTreeActionMenu.js +++ b/src/ui/pages/common/PageTreeActionMenu.js @@ -7,7 +7,7 @@ import { NEXT_PAGE_TYPE } from 'ui/pages/common/const'; import getRuntimeEnv from 'helpers/getRuntimeEnv'; import { openInNewTab } from 'helpers/urlUtils'; -const { WEBUI_APP_URL } = getRuntimeEnv(); +const { WEBUI_APP_URL, WEBUI_DEV_WORKSPACE_URL } = getRuntimeEnv(); class PageTreeActionMenu extends Component { constructor(props) { @@ -94,7 +94,7 @@ class PageTreeActionMenu extends Component { ); - const handleDesignNextPage = () => openInNewTab(WEBUI_APP_URL); + const handleDesignNextPage = () => openInNewTab(WEBUI_DEV_WORKSPACE_URL); const handlePreviewNextPage = () => openInNewTab(`${WEBUI_APP_URL}/entando-de-app/en/${page.code}.page`); return (
e.stopPropagation()} role="none" data-testid={`${page.code}-actions`}> From 8190be50cbea1f1ca6d0d69f2a1e1e680ee4fa48 Mon Sep 17 00:00:00 2001 From: Irakli Chalagashvili Date: Mon, 17 Jan 2022 18:09:59 +0400 Subject: [PATCH 10/12] webui/ENG-3042 open vscode from details screen --- src/ui/pages/add/PagesAddFormContainer.js | 13 +++++++++++-- src/ui/pages/clone/CloneFormContainer.js | 12 +++++++++++- src/ui/pages/common/const.js | 1 + src/ui/pages/edit/PagesEditFormContainer.js | 12 +++++++++++- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/ui/pages/add/PagesAddFormContainer.js b/src/ui/pages/add/PagesAddFormContainer.js index b459e8ccb..a290cf112 100644 --- a/src/ui/pages/add/PagesAddFormContainer.js +++ b/src/ui/pages/add/PagesAddFormContainer.js @@ -10,7 +10,7 @@ import { getPageTemplatesList } from 'state/page-templates/selectors'; import { getCharsets, getContentTypes, getSelectedPageLocaleTitle } from 'state/pages/selectors'; import { sendPostPage, loadSelectedPage } from 'state/pages/actions'; import { history, ROUTE_PAGE_TREE, ROUTE_PAGE_CONFIG } from 'app-init/router'; -import { PAGE_INIT_VALUES, SEO_DATA_BLANK, SEO_LANGDATA_BLANK } from 'ui/pages/common/const'; +import { NEXT_PAGE_TEMPLATE, PAGE_INIT_VALUES, SEO_DATA_BLANK, SEO_LANGDATA_BLANK } from 'ui/pages/common/const'; import { getLocale } from 'state/locale/selectors'; import getSearchParam from 'helpers/getSearchParam'; import { setVisibleModal } from 'state/modal/actions'; @@ -23,6 +23,10 @@ import { getMyGroupPermissions } from 'state/permissions/selectors'; import { fetchMyGroupPermissions } from 'state/permissions/actions'; import { fetchAllGroupEntries, fetchMyGroups } from 'state/groups/actions'; import { getGroupEntries, getGroupsList } from 'state/groups/selectors'; +import getRuntimeEnv from 'helpers/getRuntimeEnv'; +import { openInNewTab } from 'helpers/urlUtils'; + +const { WEBUI_ENABLED, WEBUI_DEV_WORKSPACE_URL } = getRuntimeEnv(); export const getDefaultLanguage = (languages) => { const defaultLang = { code: 'en' }; @@ -194,7 +198,12 @@ export const mapDispatchToProps = dispatch => ({ dispatch(setAppTourLastStep(12)); dispatch(setTourCreatedPage(data)); } - history.push(routeConverter(ROUTE_PAGE_CONFIG, { pageCode: data.code })); + if (WEBUI_ENABLED && data.pageModel === NEXT_PAGE_TEMPLATE) { + openInNewTab(WEBUI_DEV_WORKSPACE_URL); + history.push(ROUTE_PAGE_TREE); + } else { + history.push(routeConverter(ROUTE_PAGE_CONFIG, { pageCode: data.code })); + } break; } default: history.push(ROUTE_PAGE_TREE); diff --git a/src/ui/pages/clone/CloneFormContainer.js b/src/ui/pages/clone/CloneFormContainer.js index c9235bb77..61dd13951 100644 --- a/src/ui/pages/clone/CloneFormContainer.js +++ b/src/ui/pages/clone/CloneFormContainer.js @@ -13,6 +13,11 @@ import { sendClonePage } from 'state/pages/actions'; import { history, ROUTE_PAGE_TREE, ROUTE_PAGE_CONFIG } from 'app-init/router'; import { setVisibleModal } from 'state/modal/actions'; import getSearchParam from 'helpers/getSearchParam'; +import getRuntimeEnv from 'helpers/getRuntimeEnv'; +import { openInNewTab } from 'helpers/urlUtils'; +import { NEXT_PAGE_TEMPLATE } from 'ui/pages/common/const'; + +const { WEBUI_ENABLED, WEBUI_DEV_WORKSPACE_URL } = getRuntimeEnv(); export const mapStateToProps = state => ({ languages: getActiveLanguages(state), @@ -47,7 +52,12 @@ export const mapDispatchToProps = dispatch => ({ break; } case ACTION_SAVE_AND_CONFIGURE: { - history.push(routeConverter(ROUTE_PAGE_CONFIG, { pageCode: data.code })); + if (WEBUI_ENABLED && data.pageModel === NEXT_PAGE_TEMPLATE) { + openInNewTab(WEBUI_DEV_WORKSPACE_URL); + history.push(ROUTE_PAGE_TREE); + } else { + history.push(routeConverter(ROUTE_PAGE_CONFIG, { pageCode: data.code })); + } break; } default: history.push(ROUTE_PAGE_TREE); diff --git a/src/ui/pages/common/const.js b/src/ui/pages/common/const.js index a8b51193a..2181fc2b2 100644 --- a/src/ui/pages/common/const.js +++ b/src/ui/pages/common/const.js @@ -46,3 +46,4 @@ export const TEMPLATE_THUMBNAIL = { }; export const NEXT_PAGE_TYPE = 'NX'; +export const NEXT_PAGE_TEMPLATE = 'nx-page-template'; diff --git a/src/ui/pages/edit/PagesEditFormContainer.js b/src/ui/pages/edit/PagesEditFormContainer.js index a5cf3104e..058c0eadf 100644 --- a/src/ui/pages/edit/PagesEditFormContainer.js +++ b/src/ui/pages/edit/PagesEditFormContainer.js @@ -14,6 +14,11 @@ import { fetchPageTemplates } from 'state/page-templates/actions'; import { history, ROUTE_PAGE_TREE, ROUTE_PAGE_CONFIG } from 'app-init/router'; import { fetchLanguages } from 'state/languages/actions'; import { setVisibleModal } from 'state/modal/actions'; +import getRuntimeEnv from 'helpers/getRuntimeEnv'; +import { openInNewTab } from 'helpers/urlUtils'; +import { NEXT_PAGE_TEMPLATE } from 'ui/pages/common/const'; + +const { WEBUI_ENABLED, WEBUI_DEV_WORKSPACE_URL } = getRuntimeEnv(); export const FORM_ID = 'pageEdit'; @@ -44,7 +49,12 @@ export const mapDispatchToProps = (dispatch, ownProps) => ({ break; } case ACTION_SAVE_AND_CONFIGURE: { - history.push(routeConverter(ROUTE_PAGE_CONFIG, { pageCode: data.code })); + if (WEBUI_ENABLED && data.pageModel === NEXT_PAGE_TEMPLATE) { + openInNewTab(WEBUI_DEV_WORKSPACE_URL); + history.push(ROUTE_PAGE_TREE); + } else { + history.push(routeConverter(ROUTE_PAGE_CONFIG, { pageCode: data.code })); + } break; } default: history.push(ROUTE_PAGE_TREE); From aaf9418f5fba3702c57c72749652cb1680d92799 Mon Sep 17 00:00:00 2001 From: Irakli Chalagashvili Date: Mon, 17 Jan 2022 18:18:02 +0400 Subject: [PATCH 11/12] webui/ENG-3042 use locale in url --- src/ui/pages/common/PageTreeActionMenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/pages/common/PageTreeActionMenu.js b/src/ui/pages/common/PageTreeActionMenu.js index 6dd09c21d..4b3027d6d 100644 --- a/src/ui/pages/common/PageTreeActionMenu.js +++ b/src/ui/pages/common/PageTreeActionMenu.js @@ -95,7 +95,7 @@ class PageTreeActionMenu extends Component { ); const handleDesignNextPage = () => openInNewTab(WEBUI_DEV_WORKSPACE_URL); - const handlePreviewNextPage = () => openInNewTab(`${WEBUI_APP_URL}/entando-de-app/en/${page.code}.page`); + const handlePreviewNextPage = () => openInNewTab(`${WEBUI_APP_URL}/${this.props.locale}/${page.code}.page`); return (
e.stopPropagation()} role="none" data-testid={`${page.code}-actions`}> From 3559860219a0e75daa2d9fa340ef09cea467a44b Mon Sep 17 00:00:00 2001 From: Irakli Chalagashvili Date: Mon, 21 Feb 2022 20:55:11 +0400 Subject: [PATCH 12/12] Add last missing peaces --- src/api/pages.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/api/pages.js b/src/api/pages.js index a867382c7..0991a3333 100644 --- a/src/api/pages.js +++ b/src/api/pages.js @@ -322,3 +322,25 @@ export const putWebuiPage = pageObject => makeRequest({ [{ code: 1, message: `no page with the code ${pageObject.code} could be found.` }] ), }); + +export const putWebuiPageStatus = (pageCode, status) => makeRequest({ + uri: `/api/pages/${pageCode}/status`, + body: { status }, + method: METHODS.PUT, + mockResponse: { ...fetchPageResponseMap.homepage, status }, + useAuthentication: true, + domain: WEBUI_APP_MANAGEMENT_URL, + errors: () => ( + fetchPageResponseMap[pageCode] ? + [] : + [{ code: 1, message: `no page with the code ${pageCode} could be found.` }] + ), +}); + +export const deleteWebuiPage = page => makeRequest({ + uri: `/api/pages/${page.code}`, + method: METHODS.DELETE, + mockResponse: { code: `${page.code}` }, + domain: WEBUI_APP_MANAGEMENT_URL, + useAuthentication: true, +});