diff --git a/lib/components/actionBtnPanel/web.d.ts b/lib/components/actionBtnPanel/web.d.ts index 01b2724c..e15bdd30 100644 --- a/lib/components/actionBtnPanel/web.d.ts +++ b/lib/components/actionBtnPanel/web.d.ts @@ -1,10 +1,11 @@ /// import { WebComponentProps } from '../../types/Page'; import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain'; -import { OakActionBtnProps } from '../../types/oakActionBtn'; +import { OakActionBtnProps } from '../../types/AbstractComponent'; 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 index ff392fa6..0e1d9e12 100644 --- a/lib/components/actionBtnPanel/web.js +++ b/lib/components/actionBtnPanel/web.js @@ -15,9 +15,9 @@ function ItemComponent(props) { function Render(props) { var methods = props.methods, data = props.data; var t = methods.t; - var id = data.id, oakActions = data.oakActions, onClick = data.onClick; + 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, action: ele.action, type: "a", onClick: function (id, action) { return onClick(id, action); } })); + 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/list/index.d.ts b/lib/components/list/index.d.ts new file mode 100644 index 00000000..4ebc49a9 --- /dev/null +++ b/lib/components/list/index.d.ts @@ -0,0 +1,16 @@ +/// +/// +declare const _default: (props: { + oakPath?: string | undefined; + oakId?: string | undefined; + oakProjection?: AnyObject | undefined; + oakFrom?: string | undefined; + oakParentEntity?: string | undefined; + oakDisablePulldownRefresh?: boolean | undefined; + oakAutoUnmount?: boolean | undefined; + oakActions?: any[] | undefined; + oakCascadeActions?: AnyObject | undefined; + attributes?: any[] | undefined; + data?: any[] | undefined; +}) => import("react").ReactElement>; +export default _default; diff --git a/lib/components/list/index.js b/lib/components/list/index.js new file mode 100644 index 00000000..8119e1ef --- /dev/null +++ b/lib/components/list/index.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = OakComponent({ + isList: false, + properties: { + attributes: Array, + data: Array, + }, +}); diff --git a/lib/components/pureList/index.d.ts b/lib/components/pureList/index.d.ts index 31c4da38..581cd44c 100644 --- a/lib/components/pureList/index.d.ts +++ b/lib/components/pureList/index.d.ts @@ -1,17 +1,14 @@ +/// /// -import { TableProps } from 'antd'; -import type { ColumnType } from 'antd/es/table'; -declare type SelfColumn = { - path?: string; -}; -declare type Column = SelfColumn & ColumnType; -declare type Props = { - entity: string; - data: any[]; - columns: (Column | string)[]; - disableOp?: boolean; - tableProps?: TableProps; - handleClick?: (id: string, action: string) => void; -}; -declare function List(props: Props): JSX.Element; -export default List; +declare const _default: (props: { + oakPath?: string | undefined; + oakId?: string | undefined; + oakProjection?: AnyObject | undefined; + oakFrom?: string | undefined; + oakParentEntity?: string | undefined; + oakDisablePulldownRefresh?: boolean | undefined; + oakAutoUnmount?: boolean | undefined; + oakActions?: any[] | undefined; + oakCascadeActions?: AnyObject | undefined; +}) => import("react").ReactElement>; +export default _default; diff --git a/lib/components/pureList/index.js b/lib/components/pureList/index.js index bde7b3c1..1b8adc74 100644 --- a/lib/components/pureList/index.js +++ b/lib/components/pureList/index.js @@ -1,116 +1,18 @@ "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 useFeatures_1 = tslib_1.__importDefault(require("../../hooks/useFeatures")); -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 Fn(entity, path) { - var _entity = entity; - var attr; - (0, assert_1.default)(!path.includes('['), '数组索引不需要携带[],请使用arr.0.value'); - var features = (0, useFeatures_1.default)(); - var dataSchema = features.cache.getSchema(); - 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 = (0, usefulFn_1.getAttributes)(dataSchema[_entity].attributes); - var attribute = attributes[attr]; - return { - entity: _entity, - attr: attr, - attribute: attribute, - }; -} -function RenderCell(props) { - var content = props.content, entity = props.entity, path = props.path, attr = props.attr, attrType = props.attrType; - var value = (0, lodash_1.get)(content, path); - var t = (0, react_i18next_1.useTranslation)().t; - var feature = (0, useFeatures_1.default)(); - var colorDict = feature.style.getColorDict(); - 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 List(props) { - var data = props.data, columns = props.columns, entity = props.entity, _a = props.disableOp, disableOp = _a === void 0 ? false : _a, tableProps = props.tableProps; - var t = (0, react_i18next_1.useTranslation)().t; - 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 = Fn(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.type })); }; - var column = { - align: 'center', - title: title, - dataIndex: typeof ele === 'string' ? ele : ele.dataIndex, - render: render, +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, }; - // 类型如果是枚举类型,那么它的宽度一般不超过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; - return ((0, jsx_runtime_1.jsx)(actionBtnPanel_1.default, { oakId: id, oakActions: oakActions })); - } - }); - } - return ((0, jsx_runtime_1.jsx)(antd_1.Table, { dataSource: data, scroll: { x: 2200 }, columns: tableColumns })); -} -exports.default = List; + }, + 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..720d2708 --- /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, { oakId: 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/components/upsert/index.d.ts b/lib/components/upsert/index.d.ts new file mode 100644 index 00000000..1d26a5cb --- /dev/null +++ b/lib/components/upsert/index.d.ts @@ -0,0 +1,16 @@ +/// +/// +declare const _default: (props: { + oakPath?: string | undefined; + oakId?: string | undefined; + oakProjection?: AnyObject | undefined; + oakFrom?: string | undefined; + oakParentEntity?: string | undefined; + oakDisablePulldownRefresh?: boolean | undefined; + oakAutoUnmount?: boolean | undefined; + oakActions?: any[] | undefined; + oakCascadeActions?: AnyObject | undefined; + attributes?: any[] | undefined; + data?: AnyObject | undefined; +}) => import("react").ReactElement>; +export default _default; diff --git a/lib/components/upsert/index.js b/lib/components/upsert/index.js new file mode 100644 index 00000000..86c4db46 --- /dev/null +++ b/lib/components/upsert/index.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = OakComponent({ + isList: false, + properties: { + attributes: Array, + data: Object, + }, +}); diff --git a/lib/types/AbstractComponent.d.ts b/lib/types/AbstractComponent.d.ts new file mode 100644 index 00000000..fc4476f9 --- /dev/null +++ b/lib/types/AbstractComponent.d.ts @@ -0,0 +1,16 @@ +export declare type OakActionBtnProps = { + label: string; + action: string; + type?: 'a' | 'button'; + ctxType?: string; +}; +export declare type OakAbsNativeAttrDef = { + path: string; + width?: 1 | 2 | 3 | 4; +}; +export declare type OakAbsFullAttrDef = { + label: string; + value: string; + width: 1 | 2 | 3 | 4; +}; +export declare type OakAbsAttrDef = OakAbsFullAttrDef | OakAbsNativeAttrDef; diff --git a/lib/types/AbstractComponent.js b/lib/types/AbstractComponent.js new file mode 100644 index 00000000..c8ad2e54 --- /dev/null +++ b/lib/types/AbstractComponent.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 index 3e850332..49c24377 100644 --- a/lib/utils/usefulFn.d.ts +++ b/lib/utils/usefulFn.d.ts @@ -1,3 +1,5 @@ +import { EntityDict } from "oak-domain/lib/types"; +import { StorageSchema } from "oak-domain/lib/types"; export declare function getAttributes(attributes: Record): Record & { id: { type: string; @@ -15,3 +17,8 @@ export declare function getAttributes(attributes: Record): Record, entity: string, path: string): { + entity: string; + attr: string; + attribute: any; +}; diff --git a/lib/utils/usefulFn.js b/lib/utils/usefulFn.js index 2c5e59ef..cf009c80 100644 --- a/lib/utils/usefulFn.js +++ b/lib/utils/usefulFn.js @@ -1,6 +1,8 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.getAttributes = void 0; +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: { @@ -21,3 +23,37 @@ function getAttributes(attributes) { }); } 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/web.tsx b/src/components/actionBtnPanel/web.tsx index e1c136cc..8712ee21 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/AbstractComponent'; - +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 (