diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..403adbc --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +.DS_Store +node_modules +/dist + + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..964f408 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +# Ignore files: +dist +node_modules diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..63b9776 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,9 @@ +{ + "singleQuote": true, + "tabWidth": 2, + "useTabs": false, + "semi": false, + "trailingComma": "all", + "printWidth": 100, + "bracketSpacing": true +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..9e8719f --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# @emqx/shared-ui + +This repository is the home of `@emqx/shared-ui`, a centralized UI component library designed to enable consistent user interface elements across EMQX products such as EMQX Dashboard and EMQX Cloud. By fostering a shared codebase, our aim is to streamline the development process, encourage code reuse, and maintain a uniform experience for users across different EMQX platforms. + +## 🎯 Objective + +Our goal is to abstract common UI components, utilities, and theming variables that can be reused in various EMQX projects, reducing redundancy and facilitating a more efficient front-end development workflow. + +## 📦 Usage + +Components from `@emqx/shared-ui` can be easily imported into EMQX Dashboard, EMQX Cloud, or any other EMQX web application, ensuring a coherent look and feel while allowing for customization when necessary. diff --git a/package.json b/package.json new file mode 100644 index 0000000..4949566 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "@emqx/shared-ui", + "author": "EMQ FE Team", + "private": true, + "description": "Provides Shared UI components, utils, i18n, and more for consistent interfaces and code reuse across EMQX apps.", + "scripts": { + "dev": "pnpm --filter './packages/*' --parallel run dev:local", + "build": "pnpm --filter './packages/*' run build:local", + "format": "prettier --write ." + }, + "devDependencies": { + "prettier": "^3.0.3", + "typescript": "^5.2.2" + } +} diff --git a/packages/i18n/index.ts b/packages/i18n/index.ts new file mode 100644 index 0000000..923221f --- /dev/null +++ b/packages/i18n/index.ts @@ -0,0 +1 @@ +export * from './sqlTemplate' diff --git a/packages/i18n/package.json b/packages/i18n/package.json new file mode 100644 index 0000000..da07c03 --- /dev/null +++ b/packages/i18n/package.json @@ -0,0 +1,12 @@ +{ + "name": "@emqx/shared-ui-i18n", + "author": "EMQ FE Team", + "private": true, + "version": "0.0.0", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "dev:local": "tsc --watch", + "build:local": "tsc" + } +} diff --git a/packages/i18n/sqlTemplate.ts b/packages/i18n/sqlTemplate.ts new file mode 100644 index 0000000..7307260 --- /dev/null +++ b/packages/i18n/sqlTemplate.ts @@ -0,0 +1,174 @@ +export const sqlTemplate = [ + { + title: { + zh: '选择指定主题的消息', + en: 'Select messages from a topic.', + }, + scene: { + zh: '使用 SQL 选择特定主题,将命中主题的消息载荷筛选出来,可以使用通配符。', + en: 'Use SQL to select a topic, filter out the message payloads that match the topic, and support topic wildcards.', + }, + sql: `SELECT + payload as p +FROM + "t/#"`, + input: { + msg: 'hello', + }, + outputs: { + p: '{"msg": "hello"}', + }, + }, + { + title: { + zh: '同时处理客户端连接、断开连接事件', + en: 'Handle client connected and disconnect events in one SQL', + }, + scene: { + zh: '在一个 SQL 中处理多个主题/事件,避免重复创建规则。', + en: 'Simultaneous selection of multiple topics/events in one SQL, no need to repeatedly create rules.', + }, + sql: `SELECT + * +FROM + "$events/client_connected", + "$events/client_disconnected"`, + input: {}, + outputs: { + username: 'u_emqx', + timestamp: 1648870886819, + sockname: '0.0.0.0:1883', + reason: 'normal', + proto_ver: 5, + proto_name: 'MQTT', + '...': '', + }, + }, + + { + title: { + zh: 'FOREACH 处理 JSON 数组并逐个输出', + en: 'FOREACH - Process JSON arrays and output one by one', + }, + scene: { + zh: '数据类型为数组时,处理数组中的元素并逐个输出。', + en: 'When the data type is an array, process the data in the array and output one by one.', + }, + sql: `FOREACH + payload.sensors +FROM + "t/#"`, + input: { + date: '2020-04-24', + sensors: [ + { name: 'a', idx: 0 }, + { name: 'b', idx: 1 }, + { name: 'c', idx: 2 }, + ], + }, + outputs: [ + { + item: { + name: 'a', + idx: 0, + }, + '...': '', + }, + { + item: { + name: 'b', + idx: 1, + }, + '...': '', + }, + { + item: { + name: 'c', + idx: 2, + }, + '...': '', + }, + ], + }, + { + title: { + zh: 'FOREACH 处理 JSON 数组选择指定字段并添加过滤条件', + en: 'FOREACH - Process JSON arrays select specified fields and add filter conditions', + }, + scene: { + zh: '数据类型为数组时,遍历数组中的数据,选择需要的字段并添加过滤条件逐个输出。', + en: 'When the data type is an array, traverse the array to select the required fields and add filter conditions to output one by one.', + }, + sql: `FOREACH + payload.sensors +DO + clientid, + item.name as name, + item.idx as idx +INCASE + item.idx >= 1 +FROM "t/#"`, + input: { + date: '2020-04-24', + sensors: [ + { name: 'a', idx: 0 }, + { name: 'b', idx: 1 }, + { name: 'c', idx: 2 }, + ], + }, + outputs: [ + { + name: 'b', + idx: 1, + clientid: 'c_emqx', + }, + { + name: 'c', + idx: 2, + clientid: 'c_emqx', + }, + ], + }, + + { + title: { + zh: 'CASE-WHEN 从多个条件列表返回可能结果', + en: 'CASE-WHEN - Return possible results from multiple lists of conditions', + }, + scene: { + zh: '设定多个计算条件,输出不同结果。', + en: 'Set multiple calculation conditions and output different results.', + }, + sql: `SELECT + CASE WHEN payload.x < 0 THEN 0 + WHEN payload.x > 7 THEN 7 + ELSE payload.x + END as x +FROM + "t/#"`, + input: { x: 8 }, + outputs: { x: 7 }, + }, + + { + title: { + zh: '数组处理 - 从 JSON 格式的 payload 中获取嵌套的值', + en: 'Array - Get nested values from JSON-formatted payload', + }, + scene: { + zh: '处理 JSON 格式的 payload,从嵌套格式中获取所需要的值。', + en: 'Process JSON-formatted payload and get the values needed from the nested format.', + }, + sql: `SELECT + payload.data[1].id as id +FROM + "t/#"`, + input: { + data: [ + { id: 1, name: 'steve' }, + { id: 2, name: 'bill' }, + ], + }, + outputs: { id: 1 }, + }, +] diff --git a/packages/i18n/tsconfig.json b/packages/i18n/tsconfig.json new file mode 100644 index 0000000..4082f16 --- /dev/null +++ b/packages/i18n/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tsconfig.json" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..34f217b --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,36 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + .: + devDependencies: + prettier: + specifier: ^3.0.3 + version: 3.0.3 + typescript: + specifier: ^5.2.2 + version: 5.2.2 + + packages/i18n: {} + +packages: + /prettier@3.0.3: + resolution: + { + integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==, + } + engines: { node: '>=14' } + hasBin: true + dev: true + + /typescript@5.2.2: + resolution: + { + integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==, + } + engines: { node: '>=14.17' } + hasBin: true + dev: true diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..18ec407 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - 'packages/*' diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..129a89c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES2015", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": ".", + "paths": { + "@shared/*": ["packages/*/src"] + }, + "rootDirs": ["packages"], + "moduleResolution": "node", + "outDir": "./dist", + "declaration": true + }, + "include": ["packages/**/*"], + "exclude": ["node_modules", "**/*.test.ts", "**/*.spec.ts"] +}