From 8ec93f8f4de64c9cd3a74d5d49d51d9a1607fce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E6=9C=9D=E4=BC=9F?= <2211960668@qq.com> Date: Wed, 8 Mar 2023 14:08:15 +0800 Subject: [PATCH] pureList fix --- lib/components/actionBtnPanel/index.d.ts | 3 + lib/components/actionBtnPanel/index.js | 27 +++++ lib/components/actionBtnPanel/web.d.ts | 11 ++ lib/components/actionBtnPanel/web.js | 23 ++++ lib/components/pureList/index.d.ts | 3 + lib/components/pureList/index.js | 18 ++++ lib/components/pureList/web.d.ts | 23 ++++ lib/components/pureList/web.js | 85 +++++++++++++++ lib/hooks/useFeatures.d.ts | 11 ++ lib/hooks/useFeatures.js | 9 ++ lib/types/oakActionBtn.d.ts | 6 ++ lib/types/oakActionBtn.js | 2 + lib/utils/usefulFn.d.ts | 24 +++++ lib/utils/usefulFn.js | 59 +++++++++++ package.json | 2 +- src/components/actionBtnPanel/index.ts | 1 + src/components/actionBtnPanel/web.tsx | 9 +- src/components/pureList/index.json | 9 ++ src/components/pureList/index.ts | 19 ++++ .../pureList/{index.tsx => web.tsx} | 100 ++++++++---------- src/utils/usefulFn.ts | 38 +++++++ tsconfig.json | 1 + 22 files changed, 424 insertions(+), 59 deletions(-) create mode 100644 lib/components/actionBtnPanel/index.d.ts create mode 100644 lib/components/actionBtnPanel/index.js create mode 100644 lib/components/actionBtnPanel/web.d.ts create mode 100644 lib/components/actionBtnPanel/web.js create mode 100644 lib/components/pureList/index.d.ts create mode 100644 lib/components/pureList/index.js create mode 100644 lib/components/pureList/web.d.ts create mode 100644 lib/components/pureList/web.js create mode 100644 lib/hooks/useFeatures.d.ts create mode 100644 lib/hooks/useFeatures.js create mode 100644 lib/types/oakActionBtn.d.ts create mode 100644 lib/types/oakActionBtn.js create mode 100644 lib/utils/usefulFn.d.ts create mode 100644 lib/utils/usefulFn.js create mode 100644 src/components/pureList/index.json create mode 100644 src/components/pureList/index.ts rename src/components/pureList/{index.tsx => web.tsx} (60%) diff --git a/lib/components/actionBtnPanel/index.d.ts b/lib/components/actionBtnPanel/index.d.ts new file mode 100644 index 00000000..42765aac --- /dev/null +++ b/lib/components/actionBtnPanel/index.d.ts @@ -0,0 +1,3 @@ +/// +declare const _default: import("react").ComponentType; +export default _default; diff --git a/lib/components/actionBtnPanel/index.js b/lib/components/actionBtnPanel/index.js new file mode 100644 index 00000000..84d479a6 --- /dev/null +++ b/lib/components/actionBtnPanel/index.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = OakComponent({ + isList: false, + properties: { + entity: String, + actions: { + type: Array, + value: [], + }, + items: { + type: Array, + value: [], + }, + mode: { + type: String, + value: 'cell', + }, + column: { + type: Number, + value: 3, + }, + }, + data: {}, + lifetimes: {}, + methods: {}, +}); diff --git a/lib/components/actionBtnPanel/web.d.ts b/lib/components/actionBtnPanel/web.d.ts new file mode 100644 index 00000000..3434b665 --- /dev/null +++ b/lib/components/actionBtnPanel/web.d.ts @@ -0,0 +1,11 @@ +/// +import { WebComponentProps } from '../../types/Page'; +import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain'; +import { OakActionBtnProps } from '../../types/oakActionBtn'; +import { EntityDict } from 'oak-domain/lib/types/Entity'; +export default function Render(props: WebComponentProps void; +}, {}>): JSX.Element; diff --git a/lib/components/actionBtnPanel/web.js b/lib/components/actionBtnPanel/web.js new file mode 100644 index 00000000..0e1d9e12 --- /dev/null +++ b/lib/components/actionBtnPanel/web.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var jsx_runtime_1 = require("react/jsx-runtime"); +var antd_1 = require("antd"); +var web_module_less_1 = tslib_1.__importDefault(require("./web.module.less")); +var confirm = antd_1.Modal.confirm; +function ItemComponent(props) { + var id = props.id, label = props.label, type = props.type, onClick = props.onClick, action = props.action; + if (type === 'button') { + return ((0, jsx_runtime_1.jsx)(antd_1.Button, tslib_1.__assign({ onClick: function () { return onClick(id, action); } }, { children: label }))); + } + return (0, jsx_runtime_1.jsx)("a", tslib_1.__assign({ onClick: function () { return onClick(id, action); } }, { children: label })); +} +function Render(props) { + var methods = props.methods, data = props.data; + var t = methods.t; + var id = data.id, oakActions = data.oakActions, onClick = data.onClick, entity = data.entity; + return ((0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ className: web_module_less_1.default.panelContainer }, { children: (0, jsx_runtime_1.jsx)(antd_1.Space, { children: oakActions === null || oakActions === void 0 ? void 0 : oakActions.map(function (ele, index) { + return ((0, jsx_runtime_1.jsx)(ItemComponent, { id: id, label: ele.label || t("common:".concat(ele.action)) || t("".concat(entity, ":action.").concat(ele.action)), action: ele.action, type: "a", onClick: function (id, action) { return onClick(id, action); } })); + }) }) }))); +} +exports.default = Render; diff --git a/lib/components/pureList/index.d.ts b/lib/components/pureList/index.d.ts new file mode 100644 index 00000000..42765aac --- /dev/null +++ b/lib/components/pureList/index.d.ts @@ -0,0 +1,3 @@ +/// +declare const _default: import("react").ComponentType; +export default _default; diff --git a/lib/components/pureList/index.js b/lib/components/pureList/index.js new file mode 100644 index 00000000..1b8adc74 --- /dev/null +++ b/lib/components/pureList/index.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = OakComponent({ + isList: false, + formData: function (_a) { + var props = _a.props, features = _a.features; + var colorDict = features.style.getColorDict(); + var dataSchema = features.cache.getSchema(); + return { + colorDict: colorDict, + dataSchema: dataSchema, + }; + }, + properties: {}, + data: {}, + lifetimes: {}, + methods: {}, +}); diff --git a/lib/components/pureList/web.d.ts b/lib/components/pureList/web.d.ts new file mode 100644 index 00000000..a629f8be --- /dev/null +++ b/lib/components/pureList/web.d.ts @@ -0,0 +1,23 @@ +/// +import { TableProps } from 'antd'; +import type { ColumnType } from 'antd/es/table'; +import { EntityDict } from 'oak-domain/lib/types/Entity'; +import { WebComponentProps } from '../../types/Page'; +import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain'; +import { ColorDict } from 'oak-domain/lib/types/Style'; +import { StorageSchema } from 'oak-domain/lib/types/Storage'; +declare type SelfColumn = { + path?: string; +}; +declare type Column = SelfColumn & ColumnType; +export default function Render(props: WebComponentProps; + handleClick?: (id: string, action: string) => void; + colorDict: ColorDict; + dataSchema: StorageSchema; +}, {}>): JSX.Element; +export {}; diff --git a/lib/components/pureList/web.js b/lib/components/pureList/web.js new file mode 100644 index 00000000..710bce87 --- /dev/null +++ b/lib/components/pureList/web.js @@ -0,0 +1,85 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var jsx_runtime_1 = require("react/jsx-runtime"); +var react_i18next_1 = require("react-i18next"); +var antd_1 = require("antd"); +var assert_1 = tslib_1.__importDefault(require("assert")); +var usefulFn_1 = require("../../utils/usefulFn"); +var lodash_1 = require("oak-domain/lib/utils/lodash"); +var dayjs_1 = tslib_1.__importDefault(require("dayjs")); +var actionBtnPanel_1 = tslib_1.__importDefault(require("../actionBtnPanel")); +function decodeTitle(entity, attr) { + var t = (0, react_i18next_1.useTranslation)().t; + if (attr === ('$$createAt$$' || '$$updateAt$$')) { + return t("common:".concat(attr)); + } + return t("".concat(entity, ":attr.").concat(attr)); +} +function RenderCell(props) { + var content = props.content, entity = props.entity, path = props.path, attr = props.attr, attrType = props.attrType, t = props.t, colorDict = props.colorDict; + var value = (0, lodash_1.get)(content, path); + if (!value) { + return ((0, jsx_runtime_1.jsx)("div", { children: "--" })); + } + // 属性类型是enum要使用标签 + else if (attrType === 'enum') { + return ((0, jsx_runtime_1.jsx)(antd_1.Tag, tslib_1.__assign({ color: colorDict[entity][attr][String(value)] }, { children: t("".concat(entity, ":v.").concat(attr, ".").concat(value)) }))); + } + else if (attrType === 'datetime') { + return (0, jsx_runtime_1.jsx)("div", { children: (0, dayjs_1.default)(value).format('YYYY-MM-DD HH:mm') }); + } + return ((0, jsx_runtime_1.jsx)("div", { children: value })); +} +function Render(props) { + var methods = props.methods, oakData = props.data; + var t = methods.t; + var entity = oakData.entity, data = oakData.data, columns = oakData.columns, _a = oakData.disableOp, disableOp = _a === void 0 ? false : _a, tableProps = oakData.tableProps, handleClick = oakData.handleClick, colorDict = oakData.colorDict, dataSchema = oakData.dataSchema; + var tableColumns = columns.map(function (ele) { + var title = ''; + var render = function () { return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}); }; + var path; + if (typeof ele === 'string') { + path = ele; + } + else { + path = ele.path; + } + var _a = (0, usefulFn_1.resolutionPath)(dataSchema, entity, path) || {}, useEntity = _a.entity, attr = _a.attr, attribute = _a.attribute; + title = decodeTitle(useEntity, attr); + render = function (value, row) { return ((0, jsx_runtime_1.jsx)(RenderCell, { entity: entity, content: row, path: path, attr: attr, attrType: attribute === null || attribute === void 0 ? void 0 : attribute.type, t: t, colorDict: colorDict })); }; + var column = { + align: 'center', + title: title, + dataIndex: typeof ele === 'string' ? ele : ele.dataIndex, + render: render, + }; + // 类型如果是枚举类型,那么它的宽度一般不超过160 + // if (attribute?.type === 'enum') { + // Object.assign(column, {width: 160}) + // } + return Object.assign(column, typeof ele !== 'string' && ele); + }); + if (tableColumns && tableColumns) { + tableColumns.unshift({ title: '序号', width: 100, render: function (value, record, index) { + return index + 1; + }, }); + } + if (!disableOp) { + tableColumns.push({ + fixed: 'right', + align: 'center', + title: '操作', + key: 'operation', + width: 300, + render: function (value, row) { + var id = row === null || row === void 0 ? void 0 : row.id; + var oakActions = row === null || row === void 0 ? void 0 : row.oakActions; + (0, assert_1.default)(!!oakActions, '行数据中不存在oakActions, 请禁用(disableOp:true)或添加oakActions'); + return ((0, jsx_runtime_1.jsx)(actionBtnPanel_1.default, { id: id, entity: entity, oakActions: oakActions, onClick: function (id, action) { return handleClick && handleClick(id, action); } })); + } + }); + } + return ((0, jsx_runtime_1.jsx)(antd_1.Table, tslib_1.__assign({ dataSource: data, scroll: { x: 2200 }, columns: tableColumns }, tableProps))); +} +exports.default = Render; diff --git a/lib/hooks/useFeatures.d.ts b/lib/hooks/useFeatures.d.ts new file mode 100644 index 00000000..ad96ebc9 --- /dev/null +++ b/lib/hooks/useFeatures.d.ts @@ -0,0 +1,11 @@ +import { BasicFeatures } from '../features'; +import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain'; +import { Aspect, EntityDict } from 'oak-domain/lib/types'; +import { SyncContext } from 'oak-domain/lib/store/SyncRowStore'; +import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore'; +declare type ED = EntityDict & BaseEntityDict; +declare type Cxt = AsyncContext; +declare type FrontCxt = SyncContext; +declare type AD = Record>; +export default function useFeatures(): BasicFeatures; +export {}; diff --git a/lib/hooks/useFeatures.js b/lib/hooks/useFeatures.js new file mode 100644 index 00000000..164e4281 --- /dev/null +++ b/lib/hooks/useFeatures.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var features_1 = require("../platforms/web/features"); +// react 独有 +function useFeatures() { + return (0, features_1.useFeatures)(); +} +exports.default = useFeatures; +; diff --git a/lib/types/oakActionBtn.d.ts b/lib/types/oakActionBtn.d.ts new file mode 100644 index 00000000..8a2bd583 --- /dev/null +++ b/lib/types/oakActionBtn.d.ts @@ -0,0 +1,6 @@ +export declare type OakActionBtnProps = { + label: string; + action: string; + type?: 'a' | 'button'; + ctxType?: string; +}; diff --git a/lib/types/oakActionBtn.js b/lib/types/oakActionBtn.js new file mode 100644 index 00000000..c8ad2e54 --- /dev/null +++ b/lib/types/oakActionBtn.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/lib/utils/usefulFn.d.ts b/lib/utils/usefulFn.d.ts new file mode 100644 index 00000000..49c24377 --- /dev/null +++ b/lib/utils/usefulFn.d.ts @@ -0,0 +1,24 @@ +import { EntityDict } from "oak-domain/lib/types"; +import { StorageSchema } from "oak-domain/lib/types"; +export declare function getAttributes(attributes: Record): Record & { + id: { + type: string; + }; + $$createAt$$: { + type: string; + }; + $$updateAt$$: { + type: string; + }; + $$deleteAt$$: { + type: string; + }; + $$seq$$: { + type: string; + }; +}; +export declare function resolutionPath(dataSchema: StorageSchema, entity: string, path: string): { + entity: string; + attr: string; + attribute: any; +}; diff --git a/lib/utils/usefulFn.js b/lib/utils/usefulFn.js new file mode 100644 index 00000000..cf009c80 --- /dev/null +++ b/lib/utils/usefulFn.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.resolutionPath = exports.getAttributes = void 0; +var tslib_1 = require("tslib"); +var assert_1 = tslib_1.__importDefault(require("assert")); +function getAttributes(attributes) { + return Object.assign({}, attributes, { + id: { + type: 'char', + }, + $$createAt$$: { + type: 'datetime', + }, + $$updateAt$$: { + type: 'datetime', + }, + $$deleteAt$$: { + type: 'datetime', + }, + $$seq$$: { + type: 'datetime', + }, + }); +} +exports.getAttributes = getAttributes; +function resolutionPath(dataSchema, entity, path) { + var _entity = entity; + var attr; + (0, assert_1.default)(!path.includes('['), '数组索引不需要携带[],请使用arr.0.value'); + if (!dataSchema) { + return { + entity: _entity, + attr: '', + attribute: undefined, + }; + } + if (!path.includes('.')) { + attr = path; + } + else { + var strs = path.split('.'); + // 最后一个肯定是属性 + attr = strs.pop(); + // 倒数第二个可能是类名可能是索引 + _entity = strs.pop(); + // 判断是否是数组索引 + if (!Number.isNaN(Number(_entity))) { + _entity = strs.pop().split('$')[0]; + } + } + var attributes = getAttributes(dataSchema[_entity].attributes); + var attribute = attributes[attr]; + return { + entity: _entity, + attr: attr, + attribute: attribute, + }; +} +exports.resolutionPath = resolutionPath; diff --git a/package.json b/package.json index f80a8783..982b8e74 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "i18next-localstorage-backend": "^3.1.3", "i18next-resource-store-loader": "^0.1.2", "react": "^18.2.0", - "react-dom": "^18.1.0", + "react-dom": "^18.2.0", "react-i18next": "^11.18.0", "react-responsive": "^9.0.0-beta.10", "react-router-dom": "^6.3.0" diff --git a/src/components/actionBtnPanel/index.ts b/src/components/actionBtnPanel/index.ts index 718f5c8f..7343884b 100644 --- a/src/components/actionBtnPanel/index.ts +++ b/src/components/actionBtnPanel/index.ts @@ -1,4 +1,5 @@ export default OakComponent({ + isList: false, properties: { entity: String, actions: { diff --git a/src/components/actionBtnPanel/web.tsx b/src/components/actionBtnPanel/web.tsx index 1efd14c4..9d4f0b7a 100644 --- a/src/components/actionBtnPanel/web.tsx +++ b/src/components/actionBtnPanel/web.tsx @@ -11,14 +11,14 @@ import { import { WebComponentProps } from '../../types/Page'; import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain'; import { OakActionBtnProps } from '../../types/oakActionBtn'; - +import { useTranslation } from 'react-i18next'; import { EntityDict } from 'oak-domain/lib/types/Entity'; import Style from './web.module.less'; const { confirm } = Modal; type Item = { id: string, - label: string; + label?: string; action: string; type?: 'a' | 'button'; }; @@ -29,7 +29,6 @@ function ItemComponent( } ) { const { id, label, type, onClick, action } = props; - if (type === 'button') { return (