-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an option to open source FE writer generate
to enable writing annotations.
#2849
base: main
Are you sure you want to change the base?
Changes from 45 commits
b9dfe11
3dd9c4c
d246d0e
560cb17
3f89f43
d763ff1
901a6e5
82bd7e2
3d88289
a120f48
87020f2
811810b
dea250e
cee24bb
b2fed1e
e1851b8
9a5d436
20a39b7
3490ac7
da1f726
ca59e47
b01a596
e4546f7
110da8c
1bb7159
b01bef7
200aed4
4596f1f
b33329b
6e359be
8328245
ffcfe4e
ce2e16a
f059df7
bfc3c55
7263e0a
3d058c9
288b612
e1709f3
e1563f5
2e249a1
137d521
7dc70dc
2bfb2c8
de66d3c
c3e53c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@sap-ux/fiori-elements-writer': minor | ||
--- | ||
|
||
Add an option to open source FE writer to enable writing annotations. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import { sep } from 'path'; | ||
import { type CapServiceCdsInfo } from '@sap-ux/cap-config-writer'; | ||
import { getCapFolderPathsSync } from '@sap-ux/fiori-generator-shared'; | ||
import { TemplateType } from '../types'; | ||
import { | ||
generateAnnotations, | ||
type AnnotationServiceParameters, | ||
type GenerateAnnotationsOptions | ||
} from '@sap-ux/annotation-generator'; | ||
import type { Editor } from 'mem-fs-editor'; | ||
import type { OdataVersion } from '@sap-ux/odata-service-writer'; | ||
|
||
/** | ||
* The list of template types that support generation of annotations. | ||
*/ | ||
export const annotationSupportedTemplateTypes: TemplateType[] = [ | ||
TemplateType.ListReportObjectPage, | ||
TemplateType.Worklist, | ||
TemplateType.FormEntryObjectPage | ||
]; | ||
|
||
/** | ||
* Generates the annotation file path based on whether the CAP service is available. | ||
* | ||
* @param {string} [appName] - The name of the application. | ||
* @param {CapServiceCdsInfo} [capService] - The CAP service info. | ||
* @returns {string} The annotation file path based on whether the CAP service is available. | ||
*/ | ||
function getAnnotationFilePath(appName?: string, capService?: CapServiceCdsInfo): string { | ||
if (capService) { | ||
const appPath = capService.appPath ?? getCapFolderPathsSync(capService.projectPath).app; | ||
return `${appPath}${sep}${appName}${sep}annotations.cds`; | ||
} | ||
return `webapp${sep}annotations${sep}annotation.xml`; | ||
} | ||
|
||
/** | ||
* Determines if annotations can be generated for a given template. | ||
* | ||
* @param {OdataVersion} odataServiceVersion - The version of the OData service being used. | ||
* @param {TemplateType} templateType - The type of the template being used by app. | ||
* @param {boolean} [addAnnotations] - An optional flag indicating whether annotations should be enabled. | ||
* @returns {boolean} - Returns `true` if annotations can be generated, otherwise `false`. | ||
*/ | ||
export function canGenerateAnnotationsForTemplate( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it be better to use the template settings for this information, as thats its purpose, to have all template related information in one place. e.g.
Then you dont need this function: https://github.com/SAP/open-ux-tools/pull/2849/files#diff-ac5073f87858b510da65484577f6afc172f304cfec03c196415cb096ce0ebf14R45 |
||
odataServiceVersion: OdataVersion, | ||
templateType: TemplateType, | ||
addAnnotations: boolean = false | ||
): boolean { | ||
return addAnnotations && annotationSupportedTemplateTypes.includes(templateType) && odataServiceVersion === '4'; | ||
} | ||
|
||
/** | ||
* Writes annotation files for the given application configuration. | ||
* | ||
* @param {string} basePath - The base directory path of the project. | ||
* @param {object} appInfo - Information about the application. | ||
* @param {Template} appInfo.templateType - The template type of the application. | ||
* @param {string} appInfo.packageName - The package name of the application. | ||
* @param {string} appInfo.entitySetName - The entity set name associated with the annotations. | ||
* @param {CapServiceCdsInfo} [appInfo.capService] - Optional CAP service information. | ||
* @param {Editor} fs - The file system editor instance. | ||
* @returns {Promise<void>} A promise that resolves when the annotation files are successfully generated. | ||
*/ | ||
export async function writeAnnotations( | ||
basePath: string, | ||
appInfo: { | ||
templateType: TemplateType; | ||
packageName?: string; | ||
entitySetName: string; | ||
capService?: CapServiceCdsInfo; | ||
}, | ||
fs: Editor | ||
): Promise<void> { | ||
let serviceName = 'mainService'; | ||
let projectPath = basePath; | ||
|
||
// Determine whether to add line items | ||
const addLineItems = | ||
appInfo.templateType === TemplateType.ListReportObjectPage || appInfo.templateType === TemplateType.Worklist; | ||
|
||
if (appInfo.capService) { | ||
serviceName = appInfo.capService.serviceName; | ||
projectPath = appInfo.capService.projectPath; | ||
} | ||
|
||
const options: GenerateAnnotationsOptions = { | ||
entitySetName: appInfo.entitySetName, | ||
annotationFilePath: getAnnotationFilePath(appInfo.packageName, appInfo.capService), | ||
addFacets: true, | ||
addLineItems, | ||
addValueHelps: !!appInfo.capService | ||
}; | ||
|
||
const serviceParameters: AnnotationServiceParameters = { | ||
serviceName, | ||
appName: appInfo.packageName, | ||
project: projectPath | ||
}; | ||
|
||
await generateAnnotations(fs, serviceParameters, options); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ import { generate as generateUi5Project } from '@sap-ux/ui5-application-writer'; | |
import { generate as addOdataService, OdataVersion, ServiceType } from '@sap-ux/odata-service-writer'; | ||
import { generateOPAFiles } from '@sap-ux/ui5-test-writer'; | ||
import cloneDeep from 'lodash/cloneDeep'; | ||
import type { FioriElementsApp } from './types'; | ||
import type { FioriElementsApp, EntityConfig } from './types'; | ||
import { TemplateType } from './types'; | ||
import { validateApp, validateRequiredProperties } from './validate'; | ||
import { setAppDefaults, setDefaultTemplateSettings, getTemplateOptions } from './data/defaults'; | ||
|
@@ -18,10 +18,16 @@ import { | |
} from './data/templateAttributes'; | ||
import { extendManifestJson } from './data/manifestSettings'; | ||
import semVer from 'semver'; | ||
import { initI18n } from './i18n'; | ||
import { initI18n, t } from './i18n'; | ||
import { getBootstrapResourceUrls, getPackageScripts } from '@sap-ux/fiori-generator-shared'; | ||
import { generateFpmConfig } from './fpmConfig'; | ||
import { applyCAPUpdates, type CapProjectSettings } from '@sap-ux/cap-config-writer'; | ||
import type { Logger } from '@sap-ux/logger'; | ||
import { | ||
writeAnnotations, | ||
canGenerateAnnotationsForTemplate, | ||
annotationSupportedTemplateTypes | ||
} from './data/writeAnnotations'; | ||
|
||
export const V2_FE_TYPES_AVAILABLE = '1.108.0'; | ||
/** | ||
|
@@ -50,15 +56,22 @@ function getTypeScriptIgnoreGlob<T extends {}>(feApp: FioriElementsApp<T>, coerc | |
} | ||
return ignore; | ||
} | ||
|
||
/** | ||
* Generate a UI5 application based on the specified Fiori Elements floorplan template. | ||
* | ||
* @param basePath - the absolute target path where the application will be generated | ||
* @param data - configuration to generate the Fiori elements application | ||
* @param fs - an optional reference to a mem-fs editor | ||
* @param log - optional logger instance | ||
* @returns Reference to a mem-fs-editor | ||
*/ | ||
async function generate<T extends {}>(basePath: string, data: FioriElementsApp<T>, fs?: Editor): Promise<Editor> { | ||
async function generate<T extends {}>( | ||
basePath: string, | ||
data: FioriElementsApp<T>, | ||
fs?: Editor, | ||
log?: Logger | ||
): Promise<Editor> { | ||
// Load i18n translations asynchronously to ensure proper initialization. | ||
// This addresses occasional issues where i18n is not initialized in time, causing tests to fail. | ||
await initI18n(); | ||
|
@@ -223,6 +236,33 @@ async function generate<T extends {}>(basePath: string, data: FioriElementsApp<T | |
await applyCAPUpdates(fs, feApp.service.capService, settings); | ||
} | ||
|
||
// Handle annotation writing | ||
if ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we move this whole block to the if (feApp.appOptions.addAnnotations) { The index file is getting too busy and the function is too long now! Would be nicer to hide all annotation writing code to that file now? |
||
canGenerateAnnotationsForTemplate(feApp.service.version, feApp.template.type, feApp.appOptions?.addAnnotations) | ||
) { | ||
const { settings } = feApp.template; | ||
const { capService } = feApp.service; | ||
const { name: packageName } = feApp.package ?? {}; | ||
const entitySetName = (settings as T & { entityConfig?: EntityConfig })?.entityConfig?.mainEntityName ?? ''; | ||
|
||
await writeAnnotations( | ||
basePath, | ||
{ | ||
templateType: feApp.template.type, | ||
packageName: packageName, | ||
entitySetName: entitySetName, | ||
capService: capService | ||
}, | ||
fs | ||
); | ||
} else { | ||
log?.warn( | ||
t('warn.invalidTypeForAnnotationGeneration', { | ||
templateType: feApp.template.type, | ||
supportedTypes: annotationSupportedTemplateTypes | ||
}) | ||
); | ||
} | ||
return fs; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,9 @@ | |
"info": { | ||
"mockOnlyWarning": "This application was generated with a local metadata file and does not reference a live server. Please add the required server configuration or start this application with mock data using the target: npm run start-mock" | ||
}, | ||
"warn": { | ||
"invalidTypeForAnnotationGeneration": "Invalid template type '{{ templateType }}' for annotation generation. Supported types are: {{ supportedTypes }}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add additional information... "The provided option |
||
}, | ||
"error": { | ||
"unsupportedOdataVersion": "OData Version of the specified service: {{ serviceVersion }}, is not supported by the template type: {{ templateType }}", | ||
"unsupportedUI5Version": "Specified UI5 property '{{ versionProperty }}': {{ ui5Version }}, is not supported by the template type: {{ templateType }}. Please specify {{minRequiredUI5Version}} or above.", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if the
data
folder is the correct place as this is for static settings but I guess it's ok for now, not sure whatdata
means actually in this context :)