Skip to content

Commit

Permalink
feat: odata
Browse files Browse the repository at this point in the history
  • Loading branch information
meta-d committed Jan 25, 2024
1 parent 7ba4dc4 commit d3d9c9e
Show file tree
Hide file tree
Showing 30 changed files with 706 additions and 247 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish-npm-cap-odata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
registry-url: 'https://registry.npmjs.org'
- run: yarn
working-directory: ./btp-cap-monorepo
- run: yarn nx build odata
- run: yarn b:odata
working-directory: ./btp-cap-monorepo
- run: npm publish --access public --tag latest
working-directory: ./btp-cap-monorepo/dist/packages/odata
Expand Down
20 changes: 10 additions & 10 deletions btp-cap-monorepo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ This is a template for building SAP BTP and Fiori apps with [Angular](https://an
- `yarn start:btp:sandbox` run btp app in sandbox environment.
- `yarn ar` run approuter in url *http://localhost:5000/*.
- `yarn sb` run storybook to preview components in url *http://localhost:4400/*.
- `yarn start:s4:mock` Start launchpad app for S4 system environment. Open in *http://localhost:4200/*.
- `yarn start:s4:live` Start launchpad app for live S4 system environment, Open in *http://localhost:4200/*.
- `yarn start:s4h:mock` Start launchpad app for s4h system environment. Open in *http://localhost:4200/*.
- `yarn start:s4h:live` Start launchpad app for live s4h system environment, Open in *http://localhost:4200/*.

## 🛫 Start the Project

Expand All @@ -53,17 +53,17 @@ If you first run this BTP project, run `yarn deploy:btp:local` to deploy db mode

To start the development server run `yarn start` or run `nx serve launchpad` and `yarn --cwd caps/app-store w-sandbox` separately. Open your browser and navigate to http://localhost:4200/. Happy coding!

### Start S4 App
### Start s4h App

Run `yarn start:s4:live` or `yarn start:s4:mock` to start the application for S4 system.
Run `yarn start:s4h:live` or `yarn start:s4h:mock` to start the application for s4h system.

### Environments

The application has two environments, `development` and `production`. The default environment for `build` is `production`, and default environment for `serve` is `development`. You can change the environment by setting the `--configuration` option when running the `build` or `serve` command.

The features in environment are:
* **production** - enable production mode, disable debug log, and others.
* **platform** - **S4** | **BTP** | **LOCAL**
* **platform** - **S4H** | **BTP** | **LOCAL**
* **enableFiori** - enable load all Fiori apps in SAP system as menus in this application.
* **enableNotification** - enable notification service in S4HANA system.
* **enableWaterMark** - enable water mark on page of the application.
Expand All @@ -87,8 +87,8 @@ You can execute the following npm scripts to preview the application:

* **start** - starts the application (btp).
* **start:btp** - starts the application for btp.
* **start:s4:live** - starts the application for S4 system with live service.
* **start:s4:mock** - starts the application for S4 system with mock data.
* **start:s4h:live** - starts the application for s4h system with live service.
* **start:s4h:mock** - starts the application for s4h system with mock data.

### 📡 Use Live Data

Expand Down Expand Up @@ -167,14 +167,14 @@ For BTP platform, you can disable

* Base url

The deployed application needs to be opened in a non-root path, so you need to configure the base url when building the app. Replace `your_project_name` with the name of the BSP application in command `yarn b:s4:app`.
The deployed application needs to be opened in a non-root path, so you need to configure the base url when building the app. Replace `your_project_name` with the name of the BSP application in command `yarn b:s4h:app`.

```javascript
{
"b:s4:app": "nx build launchpad -- --base-href /sap/bc/ui5_ui5/sap/your_project_name/",
"b:s4h:app": "nx build launchpad -- --base-href /sap/bc/ui5_ui5/sap/your_project_name/",
}
```

* Deploy

Run `yarn d:s4` to build and deploy to s4 system, other details ref to [Deploying to ABAP](../docs/Deploy.md#deploying-to-abap).
Run `yarn d:s4h` to build and deploy to s4h system, other details ref to [Deploying to ABAP](../docs/Deploy.md#deploying-to-abap).
22 changes: 11 additions & 11 deletions btp-cap-monorepo/README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
- `yarn start:btp:sandbox` 在沙盒环境中运行 btp 应用。
- `yarn ar` 运行 approuter 链接为 *http://localhost:5000/*.
- `yarn sb` 运行 storybook 预览组件,链接为 *http://localhost:4400/*.
- `yarn start:s4:mock` 启动 S4 系统环境的启动应用,链接为 *http://localhost:4200/*.
- `yarn start:s4:live` 启动连接在线 S4 系统的启动应用,链接为 *http://localhost:4200/*.
- `yarn start:s4h:mock` 启动 S4 系统环境的启动应用,链接为 *http://localhost:4200/*.
- `yarn start:s4h:live` 启动连接在线 S4 系统的启动应用,链接为 *http://localhost:4200/*.
-
## 🛫 启动应用程序!

Expand All @@ -54,7 +54,7 @@

### 启动 S4 应用

运行 `yarn start:s4:live``yarn start:s4:mock` 以启动适用于 S4 系统的应用程序。
运行 `yarn start:s4h:live``yarn start:s4h:mock` 以启动适用于 S4 系统的应用程序。

### 环境配置

Expand All @@ -63,7 +63,7 @@
环境的特性有:

* **production** - 启用生产模式,禁用调试日志等。
* **platform** - **S4** | **BTP** | **LOCAL**
* **platform** - **S4H** | **BTP** | **LOCAL**
* **enableFiori** - 启用所有 Fiori 应用作为此应用程序中的菜单的加载。
* **enableNotification** - 启用 S4HANA 系统中的通知服务。
* **enableWaterMark** - 在应用程序的页面上启用水印。
Expand All @@ -87,12 +87,12 @@

* **start** - 启动应用程序(btp)。
* **start:btp** - 为 btp 启动应用程序。
* **start:s4:live** - 为带有实时服务的 S4 系统启动应用程序。
* **start:s4:mock** - 为带有模拟数据的 S4 系统启动应用程序。
* **start:s4h:live** - 为带有实时服务的 S4 系统启动应用程序。
* **start:s4h:mock** - 为带有模拟数据的 S4 系统启动应用程序。

### 📡 使用在线数据

当运行 `yarn start:s4:live` 本地开发应用并调用实时的 OData 服务,你需要配置代理将请求转发给 ABAP 服务器。
当运行 `yarn start:s4h:live` 本地开发应用并调用实时的 OData 服务,你需要配置代理将请求转发给 ABAP 服务器。

这里是配置文件 *src/proxy.conf.json*, 所有请求以 `/sap/` 开头的都会被转发到 **target** 服务器,并且授权账号信息 **auth** 已经被配置。

Expand All @@ -110,7 +110,7 @@

### 📋 使用模拟数据

当使用`yarn start:s4:mock` 来运行应用程序和模拟数据服务器来模拟 OData 端点时,您可以在不连接到实时 OData 服务的情况下使用应用程序,并即时生成模拟数据。
当使用`yarn start:s4h:mock` 来运行应用程序和模拟数据服务器来模拟 OData 端点时,您可以在不连接到实时 OData 服务的情况下使用应用程序,并即时生成模拟数据。

### 添加新 OData 的模拟数据

Expand Down Expand Up @@ -167,14 +167,14 @@ default: {

* 基础 URL

部署的应用程序需要在非根路径中打开,因此在构建应用程序时需要配置基础 URL。在命令 `yarn b:s4:app` 中,将 `your_project_name` 替换为 BSP 应用程序的路径名称。
部署的应用程序需要在非根路径中打开,因此在构建应用程序时需要配置基础 URL。在命令 `yarn b:s4h:app` 中,将 `your_project_name` 替换为 BSP 应用程序的路径名称。

```javascript
{
"b:s4:app": "nx build launchpad -- --base-href /sap/bc/ui5_ui5/sap/your_project_name/",
"b:s4h:app": "nx build launchpad -- --base-href /sap/bc/ui5_ui5/sap/your_project_name/",
}
```

* 部署

运行 `yarn d:s4` 以构建并部署到S4系统,其他详细信息请参考[部署到ABAP](../docs/Deploy.md#deploying-to-abap)。
运行 `yarn d:s4h` 以构建并部署到S4系统,其他详细信息请参考[部署到ABAP](../docs/Deploy.md#deploying-to-abap)。
2 changes: 1 addition & 1 deletion btp-cap-monorepo/apps/launchpad/src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const appConfig: ApplicationConfig = {
CookieService,
{
provide: APP_STORE_TOKEN,
useClass: environment.platform === 'S4' ? S4AppStoreService : BTPAppStoreService
useClass: environment.platform === 'S4H' ? S4AppStoreService : BTPAppStoreService
},
...APPINIT_PROVIDES,
ZngPageTitleStrategy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class FioriLaunchpadService {
})

constructor() {
if (environment.platform === 'S4' && environment.enableFiori) {
if (environment.platform === 'S4H' && environment.enableFiori) {
this.loadFLPMenus().then()
this.loadCookie()
const localPageSets = this.localStorage.getItem<PageSets[]>(SAPFioriPageSetsName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class MenusService {

readonly flpMenus = this.flpService.routes
readonly flpLoading = computed(() => {
return environment.platform === 'S4' && environment.enableFiori && !this.flpMenus()
return environment.platform === 'S4H' && environment.enableFiori && !this.flpMenus()
})
readonly menus = computed(() => {
return [...this.tAppMenus(), ...(this.flpMenus() ?? [])]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ODataQueryOptions, StoreStatus, defineODataStore } from '@metad/cap-odata'
import { Keys, ODataQueryOptions, StoreStatus, defineODataStore } from '@metad/cap-odata'

const demoODataStore = defineODataStore('OData.svc', {
base: '/odata.org/V3/OData/'
Expand All @@ -21,6 +21,11 @@ export async function queryProducts(options?: ODataQueryOptions) {
return result
}

export async function readProduct(keys: Keys, options?: ODataQueryOptions) {
const { read } = useDemoODataStore()
return await read<ProductType>('Products', {"ID": 8}, options)
}

export async function helpProductCategory(options?: ODataQueryOptions) {
const { query } = useDemoODataStore()
const result = await query<CategoryType>('Categories', options)
Expand All @@ -39,6 +44,11 @@ export async function helpProductDetails(options?: ODataQueryOptions) {
return result
}

export async function cloneCatalog() {
const { functionImport } = useDemoODataStore()
return await functionImport('CloneCatalog', {sourceId: 1, targetId: 2, title: 'test'})
}

export type ProductType = {
ID: string
Name: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { toSignal } from '@angular/core/rxjs-interop'
import { FormsModule } from '@angular/forms'
import { EMPTY, catchError, from, map, tap } from 'rxjs'
import { ZngAntdModule } from '../../../core/shared.module'
import { queryRisks } from '../../../stores'
import { queryRisks } from './risk'

@Component({
standalone: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Injectable, inject } from '@angular/core'
import { toSignal } from '@angular/core/rxjs-interop'
import { NGXLogger } from 'ngx-logger'
import { BehaviorSubject, map } from 'rxjs'
import { getCurrentUser } from '../auth'
import { getCurrentUser } from './auth'
import { upsertPersonalization, readPersonalization } from './personalization'
import { IAppStore, AppStoreState, DefaultPersonalization, PersContainerId, PersonalizationType, PersContainer } from '../app'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { StoreStatus, defineODataStore } from '@metad/cap-odata'

type ODataUserType = {
ID: string
Name: string
}

const authStore = defineODataStore('auth', {
base: '/api'
})
Expand All @@ -14,5 +19,5 @@ export const useAuthStore = () => {

export async function getCurrentUser() {
const { functionImport } = useAuthStore()
return await functionImport('current')
return await functionImport<ODataUserType>('current')
}
2 changes: 2 additions & 0 deletions btp-cap-monorepo/apps/launchpad/src/app/stores/btp/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './app-store.btp'
export * from './personalization'
8 changes: 3 additions & 5 deletions btp-cap-monorepo/apps/launchpad/src/app/stores/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
export * from './epm'
export * from './auth'
export * from './btp/auth'
export * from './app'
export * from './PAGE_BUILDER_PERS'
export * from './notification_srv'
export * from './btp/risk'
export * from './btp/app-store.btp'
export * from './s4/app-store.s4'
export * from './s4/INTEROP'
export * from './btp/'
export * from './s4h/'
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ export const useNotificationStore = () => {
export async function getBadgeNumber(): Promise<number> {
const { functionImport } = notificationStore

const result = await functionImport('GetBadgeNumber')
const result = await functionImport<{value: number}>('GetBadgeNumber')

return result.value as number
return result.value
}

export async function resetBadgeNumber() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const useESHSearchStore = () => {
return eshStore
}

export type UserType = {
export type ODataUserType = {
Id: string
Name: string
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Injectable, inject } from '@angular/core'
import { toSignal } from '@angular/core/rxjs-interop'
import { NGXLogger } from 'ngx-logger'
import { BehaviorSubject, map } from 'rxjs'
import { UserType, useESHSearchStore } from './ESH_SEARCH'
import { ODataUserType, useESHSearchStore } from './ESH_SEARCH'
import { PersContainerType, useINTEROPStore } from './INTEROP'
import { IAppStore, AppStoreState, DefaultPersonalization, PersContainerId, PersonalizationType } from '../app'

Expand All @@ -29,7 +29,7 @@ export class S4AppStoreService implements IAppStore {

async refreshUser() {
const { read } = useESHSearchStore()
const user = await read<UserType>('Users', { Id: '<current>' })
const user = await read<ODataUserType>('Users', { Id: '<current>' })
.then((result) => {
return {
id: result.Id,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { StoreStatus, defineODataStore } from '@metad/cap-odata'

/**
* Define the private store for the authorization OData service.
*/
const authStore = defineODataStore('ZNG_AUTHORIZATION_SRV')

/**
* Export a hook to access the authorization store.
* - If the store is not yet initialized, it will be initialized.
* - If the store is in error state, it will be reinitialized.
*
* @returns store for odata service
*/
export const useAuthStore = () => {
const { store, init } = authStore
if (store.value.status === StoreStatus.init || store.value.status === StoreStatus.error) {
init()
}
return authStore
}

/**
* Deconstruct actions from the store using the hook
*
* @returns
*/
export async function checkAuthorization() {
const { save } = useAuthStore()

const result = await save('ActionSet', {})

return result
}
3 changes: 3 additions & 0 deletions btp-cap-monorepo/apps/launchpad/src/app/stores/s4h/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './app-store.s4'
export * from './ESH_SEARCH'
export * from './INTEROP'
2 changes: 1 addition & 1 deletion btp-cap-monorepo/apps/launchpad/src/environments/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export type IEnvironment = {
/**
* 此 Web 应用所适用的服务器平台
*/
platform: 'S4' | 'BTP' | 'LOCAL'
platform: 'S4H' | 'BTP' | 'LOCAL'
/**
* 启用兼容 S4 系统 Fiori Apps 功能
*/
Expand Down
9 changes: 5 additions & 4 deletions btp-cap-monorepo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@
"start:btp": "concurrently \"nx serve launchpad\" \"yarn --cwd caps/app-store w\"",
"start:btp:sandbox": "concurrently \"nx serve launchpad\" \"yarn --cwd caps/app-store w-sandbox\"",
"deploy:btp:local": "yarn --cwd caps/app-store deploy:local",
"start:s4:mock": "concurrently \"nx serve launchpad -c mock\" \"node apps/launchpad/src/mock/index.mjs\"",
"start:s4:live": "nx serve launchpad",
"start:s4h:mock": "concurrently \"nx serve launchpad -c mock\" \"node apps/launchpad/src/mock/index.mjs\"",
"start:s4h:live": "nx serve launchpad",
"ar": "yarn bapp && yarn --cwd caps/app-store approuter",
"sb": "yarn nx run launchpad:storybook",
"b:odata": "rm -rf dist/packages/odata/ && yarn nx build odata && cp packages/odata/README.md dist/packages/odata/",
"b:btp:app": "nx build launchpad -- --base-href /blp/ && rm -rf ./caps/app-store/app/blp/ && mv ./dist/apps/launchpad/browser/ ./caps/app-store/app/blp/",
"b:btp": "yarn b:btp:app && yarn --cwd caps/app-store build",
"d:btp": "yarn --cwd caps/app-store deploy",
"b:s4:app": "nx build launchpad -- --base-href /sap/bc/ui5_ui5/sap/your_project_name/",
"b:s4h:app": "nx build launchpad -- --base-href /sap/bc/ui5_ui5/sap/your_project_name/",
"archive": "cd dist/apps/launchpad/browser && npx bestzip ../../../../archive.zip * .Ui5RepositoryBinaryFiles",
"d:fiori": "fiori deploy --archive-path ./archive.zip --config ui5-deploy.yaml --yes",
"d:s4": "yarn b:s4:app && yarn archive && yarn d:fiori && rimraf ./archive.zip",
"d:s4h": "yarn b:s4h:app && yarn archive && yarn d:fiori && rimraf ./archive.zip",
"b:performance": "yarn nx build --stats-json --sourceMap=true launchpad",
"stats": "npx webpack-bundle-analyzer ./dist/apps/launchpad/stats.json"
},
Expand Down
Loading

0 comments on commit d3d9c9e

Please sign in to comment.