Skip to content

Commit

Permalink
feat(illustration): use illustration name as default module export (#…
Browse files Browse the repository at this point in the history
…8074)

* feat(illustration): use illustration name as default module export

* chore: generate type definition for imports

* chore: fix illustration export string

* chore: fix import of js and add documentation

* chore: correct illustration loading

---------

Co-authored-by: Nayden Naydenov <nnaydenow.work@sap.com>
  • Loading branch information
nnaydenow and Nayden Naydenov committed Jan 15, 2024
1 parent 4cdf30a commit a9c0705
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 81 deletions.
33 changes: 11 additions & 22 deletions packages/base/src/asset-registries/Illustrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,26 +50,16 @@ const getCollection = () => {
*/
const processName = (name: string) => {
let collection = getCollection();
const isTnt = name.startsWith("Tnt");
const set = isTnt ? "tnt" : "fiori";
const [set, illustrationName] = name.split("/");
let registryKey = `${set}/${collection}/${illustrationName}`;

let registryKey = `${set}/${collection}/${name}`;
let loaderKey = `${collection}/${name}`;

if (!loaders.has(loaderKey) && collection !== FALLBACK_COLLECTION) {
if (!loaders.has(registryKey) && collection !== FALLBACK_COLLECTION) {
collection = FALLBACK_COLLECTION;
loaderKey = `${collection}/${name}`;
registryKey = `${set}/${collection}/${name}`;
}

if (isTnt) {
name = name.replace(/^Tnt/, "");
registryKey = `${set}/${collection}/${name}`;
registryKey = `${set}/${collection}/${illustrationName}`;
}

return {
registryKey,
loaderKey,
collection,
};
};
Expand All @@ -90,18 +80,17 @@ const registerIllustrationLoader = (illustrationName: string, loader: Illustrati
};

const _loadIllustrationOnce = (illustrationName: string) => {
const { loaderKey } = processName(illustrationName);

if (!illustrationPromises.has(loaderKey)) {
if (!loaders.has(loaderKey)) {
const illustrationPath = illustrationName.startsWith("Tnt") ? `tnt/${illustrationName.replace(/^Tnt/, "")}` : illustrationName;
const { registryKey } = processName(illustrationName);
if (!illustrationPromises.has(registryKey)) {
if (!loaders.has(registryKey)) {
const illustrationPath = illustrationName.startsWith("fiori/") ? illustrationName.replace("fiori/", "") : illustrationName;
throw new Error(`No loader registered for the ${illustrationName} illustration. Probably you forgot to import the "@ui5/webcomponents-fiori/dist/illustrations/${illustrationPath}.js" module. Or you can import the "@ui5/webcomponents-fiori/dist/illustrations/AllIllustrations.js" module that will make all illustrations available, but fetch only the ones used.`);
}

const loadIllustrations = loaders.get(loaderKey)!;
illustrationPromises.set(loaderKey, loadIllustrations(loaderKey));
const loadIllustrations = loaders.get(registryKey)!;
illustrationPromises.set(registryKey, loadIllustrations(registryKey));
}
return illustrationPromises.get(loaderKey);
return illustrationPromises.get(registryKey);
};

const getIllustrationDataSync = (illustrationName: string) => {
Expand Down
4 changes: 0 additions & 4 deletions packages/fiori/package-scripts.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ const options = {
dynamicImports: {
outputFile: "src/generated/js-imports/Illustrations.ts",
location: '../../illustrations',
prefix: "",
filterOut
}
},
Expand All @@ -43,7 +42,6 @@ const options = {
dynamicImports: {
outputFile: "src/generated/js-imports/IllustrationsTNT.ts",
location: '../../illustrations/tnt',
prefix: "Tnt",
filterOut
}
},
Expand All @@ -57,7 +55,6 @@ const options = {
dynamicImports: {
outputFile: "src/generated/js-imports/IllustrationsV5TNT.ts",
location: '../../illustrations-v5/tnt',
prefix: "Tnt",
filterOut
}
},
Expand All @@ -71,7 +68,6 @@ const options = {
dynamicImports: {
outputFile: "src/generated/js-imports/IllustrationsV5TNTHC.ts",
location: '../../illustrations-v5/tnt/hc',
prefix: "Tnt",
filterOut
}
},
Expand Down
54 changes: 40 additions & 14 deletions packages/fiori/src/IllustratedMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ import IllustratedMessageCss from "./generated/themes/IllustratedMessage.css.js"
// Template
import IllustratedMessageTemplate from "./generated/templates/IllustratedMessageTemplate.lit.js";

const getEffectiveIllustrationName = (name: string): string => {
if (name.startsWith("Tnt")) {
return name.replace("Tnt", "tnt/");
}

if (name.includes("/")) {
return name;
}

return `fiori/${name}`;
};

/**
* @class
*
Expand Down Expand Up @@ -81,22 +93,34 @@ import IllustratedMessageTemplate from "./generated/templates/IllustratedMessage
class IllustratedMessage extends UI5Element {
/**
* Defines the illustration name that will be displayed in the component.
* <br><br>
* <b>Note:</b> By default the <code>BeforeSearch</code> illustration is loaded.
* <br>
* Example:
* <br>
* <code>name='BeforeSearch'</code>, <code>name='UnableToUpload'</code>, etc..
* <br>
* <br>
* <b>Note:</b> To use the TNT illustrations,
* you need to set the <code>tnt</code> or <code>Tnt</code> prefix in front of the icon's name.
* <br>
* Example:
* <br>
* <code>name='tnt/Avatar'</code> or <code>name='TntAvatar'</code>.
* <br>
* <br>
* <b>Note:</b> By default the <code>BeforeSearch</code> illustration is loaded.
* When using an illustration type, other than the default, it should be loaded in addition:
* <br>
* <code>import "@ui5/webcomponents-fiori/dist/illustrations/NoData.js";</code>
* <br><br>
* <b>Note:</b> TNT illustrations cointain <code>Tnt</code> prefix in their name.
* You can import them removing the <code>Tnt</code> prefix like this:
* <br>
* <br>
* For TNT illustrations:
* <br>
* <code>import "@ui5/webcomponents-fiori/dist/illustrations/tnt/SessionExpired.js";</code>
* @default "BeforeSearch"
* @public
*/
@property({ type: IllustrationMessageType, defaultValue: IllustrationMessageType.BeforeSearch })
name!: `${IllustrationMessageType}`;
@property({ type: String, defaultValue: IllustrationMessageType.BeforeSearch })
name!: string;

/**
* Determines which illustration breakpoint variant is used.
Expand Down Expand Up @@ -267,18 +291,18 @@ class IllustratedMessage extends UI5Element {
}

async onBeforeRendering() {
let illustrationData = getIllustrationDataSync(this.name);

// Gets the current illustration name given in the "name" attribute
const currentIllustration = this.getAttribute("name") as IllustrationMessageType;
let effectiveName = getEffectiveIllustrationName(this.name);
let illustrationData = getIllustrationDataSync(effectiveName);

if (this.hasAttribute("name") && !this.isValidIllustration(currentIllustration)) {
if (this.hasAttribute("name") && !this.isValidIllustration(effectiveName)) {
effectiveName = getEffectiveIllustrationName(IllustrationMessageType.BeforeSearch);
// eslint-disable-next-line
console.warn(`The illustration "${currentIllustration!}" does not exist. The default illustration "${IllustrationMessageType.BeforeSearch}" is loaded instead.`);
console.warn(`The illustration "${effectiveName!}" does not exist. The default illustration "${IllustrationMessageType.BeforeSearch}" is loaded instead.`);
}

if (illustrationData === undefined) {
illustrationData = await getIllustrationData(this.name);
illustrationData = await getIllustrationData(effectiveName);
}

this.spotSvg = illustrationData!.spotSvg;
Expand Down Expand Up @@ -439,7 +463,9 @@ class IllustratedMessage extends UI5Element {
return !!this.actions.length && this.media !== IllustratedMessage.MEDIA.BASE;
}

isValidIllustration(currentIllustration: `${IllustrationMessageType}`): boolean {
isValidIllustration(currentIllustration: string): boolean {
currentIllustration = currentIllustration.startsWith("tnt/") ? currentIllustration.replace("tnt/", "Tnt") : currentIllustration.replace("fiori/", "");

return currentIllustration in IllustrationMessageType;
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/tools/components-package/nps.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const getScripts = (options) => {
const createIllustrationsJSImportsScript = illustrations.join(" && ");

// The script creates the "src/generated/js-imports/Illustration.js" file that registers loaders (dynamic JS imports) for each illustration
const createIllustrationsLoadersScript = illustrationsData.map(illustrations => `node ${LIB}/generate-js-imports/illustrations.js ${illustrations.destinationPath} ${illustrations.dynamicImports.outputFile} ${illustrations.collection} ${illustrations.dynamicImports.location} ${illustrations.dynamicImports.prefix || '\"\"'} ${illustrations.dynamicImports.filterOut.join(" ")}`).join(" && ");
const createIllustrationsLoadersScript = illustrationsData.map(illustrations => `node ${LIB}/generate-js-imports/illustrations.js ${illustrations.destinationPath} ${illustrations.dynamicImports.outputFile} ${illustrations.set} ${illustrations.collection} ${illustrations.dynamicImports.location} ${illustrations.dynamicImports.filterOut.join(" ")}`).join(" && ");

const tsOption = options.typescript;
const tsCommandOld = tsOption ? "tsc" : "";
Expand Down
52 changes: 21 additions & 31 deletions packages/tools/lib/create-illustrations/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const generate = async () => {
const destPath = process.argv[6];
const collection = process.argv[7];
const fileNamePattern = new RegExp(`${illustrationsPrefix}-.+-(.+).svg`);
// collect each illustration name because each one should have Sample.js file
// collect each illustration name because each one should have Sample.js file
const fileNames = new Set();

try {
Expand All @@ -75,7 +75,7 @@ const generate = async () => {
return `export default \`${svgContent}\`;`
};
const svgToJs = async fileName => {
const svg = await fs.readFile(path.join(srcPath, fileName), {encoding: "utf-8"});
const svg = await fs.readFile(path.join(srcPath, fileName), { encoding: "utf-8" });
const fileContent = svgImportTemplate(svg);
fileName = fileName.replace(/\.svg$/, ".js");

Expand All @@ -94,58 +94,47 @@ const generate = async () => {

const illustrationNameUpperCase = illustrationNameForTranslation.toUpperCase();

return defaultText ? `import { registerIllustration } from "@ui5/webcomponents-base/dist/asset-registries/Illustrations.js";
return `import { registerIllustration } from "@ui5/webcomponents-base/dist/asset-registries/Illustrations.js";
import dialogSvg from "./${illustrationsPrefix}-Dialog-${illustrationName}.js";
import sceneSvg from "./${illustrationsPrefix}-Scene-${illustrationName}.js";
import spotSvg from "./${illustrationsPrefix}-Spot-${illustrationName}.js";
import {
import spotSvg from "./${illustrationsPrefix}-Spot-${illustrationName}.js";${
defaultText ? `import {
IM_TITLE_${illustrationNameUpperCase},
IM_SUBTITLE_${illustrationNameUpperCase},
} from "../generated/i18n/i18n-defaults.js";
} from "../generated/i18n/i18n-defaults.js";` : ``}
const name = "${illustrationName}";
const set = "${illustrationSet}";
const collection = "${collection}";
const collection = "${collection}";${defaultText ? `
const title = IM_TITLE_${illustrationNameUpperCase};
const subtitle = IM_SUBTITLE_${illustrationNameUpperCase};
const subtitle = IM_SUBTITLE_${illustrationNameUpperCase};` : ``}
registerIllustration(name, {
dialogSvg,
sceneSvg,
spotSvg,
spotSvg,${defaultText ? `
title,
subtitle,
subtitle,` : ``}
set,
collection,
});
export default "${illustrationSet === "fiori" ? "" : `${illustrationSet}/`}${illustrationName}";
export {
dialogSvg,
sceneSvg,
spotSvg,
};` :
`import { registerIllustration } from "@ui5/webcomponents-base/dist/asset-registries/Illustrations.js";
import dialogSvg from "./${illustrationsPrefix}-Dialog-${illustrationName}.js";
import sceneSvg from "./${illustrationsPrefix}-Scene-${illustrationName}.js";
import spotSvg from "./${illustrationsPrefix}-Spot-${illustrationName}.js";
const name = "${illustrationName}";
const set = "${illustrationSet}";
const collection = "${collection}";
};`
};

registerIllustration(name, {
dialogSvg,
sceneSvg,
spotSvg,
set,
collection,
});
const illustrationTypeDefinition = illustrationName => {
return `declare const dialogSvg: string;
declare const sceneSvg: string;
declare const spotSvg: string;
declare const _default: "${illustrationSet === "fiori" ? "" : `${illustrationSet}/`}${illustrationName}";
export {
dialogSvg,
sceneSvg,
spotSvg,
};`
export default _default;
export { dialogSvg, sceneSvg, spotSvg };`
};

await fs.mkdir(destPath, { recursive: true });
Expand All @@ -165,6 +154,7 @@ export {

for (let illustrationName of fileNames) {
promises.push(fs.writeFile(path.join(destPath, `${illustrationName}.js`), illustrationImportTemplate(illustrationName)));
promises.push(fs.writeFile(path.join(destPath, `${illustrationName}.d.ts`), illustrationTypeDefinition(illustrationName)));
}

return Promise.all(promises);
Expand Down
18 changes: 9 additions & 9 deletions packages/tools/lib/generate-js-imports/illustrations.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ const generateAvailableIllustrationsArray = (fileNames, exclusionPatterns = [])
);
};

const generateDynamicImportsFileContent = (dynamicImports, availableIllustrations, collection, prefix = "") => {
const generateDynamicImportsFileContent = (dynamicImports, availableIllustrations, collection, set, prefix = "") => {
return `// @ts-nocheck
import { registerIllustrationLoader } from "@ui5/webcomponents-base/dist/asset-registries/Illustrations.js";
export const loadIllustration = async (illustrationName) => {
const collectionAndPrefix = "${collection}/${prefix}";
const collectionAndPrefix = "${set}/${collection}/${prefix}";
const cleanIllustrationName = illustrationName.startsWith(collectionAndPrefix) ? illustrationName.replace(collectionAndPrefix, "") : illustrationName;
switch (cleanIllustrationName) {
${dynamicImports}
Expand All @@ -41,7 +41,7 @@ const loadAndCheck = async (illustrationName) => {
};
${availableIllustrations}.forEach((illustrationName) =>
registerIllustrationLoader(\`${collection}/${prefix}\${illustrationName}\`, loadAndCheck)
registerIllustrationLoader(\`${set}/${collection}/${prefix}\${illustrationName}\`, loadAndCheck)
);
`;
};
Expand All @@ -52,7 +52,7 @@ const getMatchingFiles = async (folder, pattern) => {
};

const generateIllustrations = async (config) => {
const { inputFolder, outputFile, collection, location, prefix, filterOut } = config;
const { inputFolder, outputFile, collection, location, prefix, filterOut, set } = config;

const normalizedInputFolder = path.normalize(inputFolder);
const normalizedOutputFile = path.normalize(outputFile);
Expand All @@ -62,7 +62,7 @@ const generateIllustrations = async (config) => {
const dynamicImports = await generateDynamicImportLines(illustrations, location, filterOut);
const availableIllustrations = generateAvailableIllustrationsArray(illustrations, filterOut);

const contentDynamic = generateDynamicImportsFileContent(dynamicImports, availableIllustrations, collection, prefix);
const contentDynamic = generateDynamicImportsFileContent(dynamicImports, availableIllustrations, collection, set, prefix);

await fs.mkdir(path.dirname(normalizedOutputFile), { recursive: true });
await fs.writeFile(normalizedOutputFile, contentDynamic);
Expand All @@ -74,10 +74,10 @@ const generateIllustrations = async (config) => {
const config = {
inputFolder: process.argv[2],
outputFile: process.argv[3],
collection: process.argv[4],
location: process.argv[5],
prefix: process.argv[6],
filterOut: process.argv.slice(7),
set: process.argv[4],
collection: process.argv[5],
location: process.argv[6],
filterOut: process.argv.slice[7],
};

// Run the generation process
Expand Down

0 comments on commit a9c0705

Please sign in to comment.