From ea417ba23c59c902210ed7701e1bead86ef804ac Mon Sep 17 00:00:00 2001 From: Thu Pham Date: Wed, 6 Mar 2024 12:23:23 -0800 Subject: [PATCH 01/14] Implement DatetimeControl and add tests --- package.json | 7 +- pnpm-lock.yaml | 121 +++++++++++++++++++------- src/controls/DatetimeControl.test.tsx | 34 ++++++++ src/controls/DatetimeControl.tsx | 21 +++++ src/renderers.ts | 12 ++- src/testSchemas/datetimeSchema.ts | 36 ++++++++ 6 files changed, 197 insertions(+), 34 deletions(-) create mode 100644 src/controls/DatetimeControl.test.tsx create mode 100644 src/controls/DatetimeControl.tsx create mode 100644 src/testSchemas/datetimeSchema.ts diff --git a/package.json b/package.json index 96de2c3..5f8b3e3 100644 --- a/package.json +++ b/package.json @@ -47,9 +47,10 @@ "@ant-design/icons": "^5.3.0", "@jsonforms/core": "^3.2.1", "@jsonforms/react": "^3.2.1", - "@types/lodash.isempty": "^4.4.9", - "antd": "^5.14.0", "lodash.isempty": "^4.4.0", + "antd": "^5.14.0", + "date-fns": "^3.3.1", + "rc-picker": "^4.2.0", "react": "^17 || ^18" }, "devDependencies": { @@ -74,6 +75,7 @@ "@typescript-eslint/parser": "^6.14.0", "@vitejs/plugin-react": "^4.2.1", "antd": "^5.14.0", + "date-fns": "^3.3.1", "eslint": "^8.55.0", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", @@ -82,6 +84,7 @@ "jsdom": "^24.0.0", "json-schema-to-ts": "^3.0.0", "lodash.isempty": "^4.4.0", + "rc-picker": "^4.2.0", "react": "^18.2.0", "react-dom": "^18.2.0", "semantic-release": "^23.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e5f5b7..03a85bd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -67,7 +67,10 @@ devDependencies: version: 4.2.1(vite@5.0.11) antd: specifier: ^5.14.0 - version: 5.14.0(react-dom@18.2.0)(react@18.2.0) + version: 5.14.0(date-fns@3.4.0)(react-dom@18.2.0)(react@18.2.0) + date-fns: + specifier: ^3.3.1 + version: 3.4.0 eslint: specifier: ^8.55.0 version: 8.56.0 @@ -92,6 +95,9 @@ devDependencies: lodash.isempty: specifier: ^4.4.0 version: 4.4.0 + rc-picker: + specifier: ^4.2.0 + version: 4.3.0(date-fns@3.4.0)(react-dom@18.2.0)(react@18.2.0) react: specifier: ^18.2.0 version: 18.2.0 @@ -2243,11 +2249,11 @@ packages: resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==} dev: true - /@octokit/plugin-paginate-rest@9.2.0(@octokit/core@5.1.0): - resolution: {integrity: sha512-NKi0bJEZqOSbBLMv9kdAcuocpe05Q2xAXNLTGi0HN2GSMFJHNZuSoPNa0tcQFTOFCKe+ZaYBZ3lpXh1yxgUDCA==} + /@octokit/plugin-paginate-rest@9.2.1(@octokit/core@5.1.0): + resolution: {integrity: sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==} engines: {node: '>= 18'} peerDependencies: - '@octokit/core': '>=5' + '@octokit/core': '5' dependencies: '@octokit/core': 5.1.0 '@octokit/types': 12.6.0 @@ -2983,6 +2989,23 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true + /@rc-component/trigger@2.0.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-niwKADPdY5dhdIblV6uwSayVivwo2uUISfJqri+/ovYQcH/omxDYBJKo755QKeoIIsWptxnRpgr7reEnNEZGFg==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.23.9 + '@rc-component/portal': 1.1.2(react-dom@18.2.0)(react@18.2.0) + classnames: 2.5.1 + rc-motion: 2.9.0(react-dom@18.2.0)(react@18.2.0) + rc-resize-observer: 1.4.0(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.38.1(react-dom@18.2.0)(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + /@rollup/pluginutils@5.1.0: resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} @@ -3131,7 +3154,7 @@ packages: semantic-release: '>=20.1.0' dependencies: '@octokit/core': 5.1.0 - '@octokit/plugin-paginate-rest': 9.2.0(@octokit/core@5.1.0) + '@octokit/plugin-paginate-rest': 9.2.1(@octokit/core@5.1.0) '@octokit/plugin-retry': 6.0.1(@octokit/core@5.1.0) '@octokit/plugin-throttling': 8.2.0(@octokit/core@5.1.0) '@semantic-release/error': 4.0.0 @@ -3151,8 +3174,8 @@ packages: - supports-color dev: true - /@semantic-release/npm@11.0.2(semantic-release@23.0.2): - resolution: {integrity: sha512-owtf3RjyPvRE63iUKZ5/xO4uqjRpVQDUB9+nnXj0xwfIeM9pRl+cG+zGDzdftR4m3f2s4Wyf3SexW+kF5DFtWA==} + /@semantic-release/npm@11.0.3(semantic-release@23.0.2): + resolution: {integrity: sha512-KUsozQGhRBAnoVg4UMZj9ep436VEGwT536/jwSqB7vcEfA6oncCUU7UIYTRdLx7GvTtqn0kBjnkfLVkcnBa2YQ==} engines: {node: ^18.17 || >=20} peerDependencies: semantic-release: '>=20.1.0' @@ -3163,8 +3186,8 @@ packages: fs-extra: 11.2.0 lodash-es: 4.17.21 nerf-dart: 1.0.0 - normalize-url: 8.0.0 - npm: 10.4.0 + normalize-url: 8.0.1 + npm: 10.5.0 rc: 1.2.8 read-pkg: 9.0.1 registry-auth-token: 5.0.2 @@ -4797,7 +4820,7 @@ packages: engines: {node: '>=12'} dev: true - /antd@5.14.0(react-dom@18.2.0)(react@18.2.0): + /antd@5.14.0(date-fns@3.4.0)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-LdRJnYd8dTykR2xr483zNE0mBKmWHMLqmjkfcX4otQRD0kaZjOwSmN74vMC70jnMM8oqhWILFjWy3dEy/E1W6w==} peerDependencies: react: '>=16.9.0' @@ -4831,7 +4854,7 @@ packages: rc-motion: 2.9.0(react-dom@18.2.0)(react@18.2.0) rc-notification: 5.3.0(react-dom@18.2.0)(react@18.2.0) rc-pagination: 4.0.4(react-dom@18.2.0)(react@18.2.0) - rc-picker: 4.0.0-alpha.44(dayjs@1.11.10)(react-dom@18.2.0)(react@18.2.0) + rc-picker: 4.0.0-alpha.44(date-fns@3.4.0)(dayjs@1.11.10)(react-dom@18.2.0)(react@18.2.0) rc-progress: 3.5.1(react-dom@18.2.0)(react@18.2.0) rc-rate: 2.12.0(react-dom@18.2.0)(react@18.2.0) rc-resize-observer: 1.4.0(react-dom@18.2.0)(react@18.2.0) @@ -5672,6 +5695,10 @@ packages: whatwg-url: 14.0.0 dev: true + /date-fns@3.4.0: + resolution: {integrity: sha512-Akz4R8J9MXBsOgF1QeWeCsbv6pntT5KCPjU0Q9prBxVmWJYPLhwAIsNg3b0QAdr0ttiozYLD3L/af7Ra0jqYXw==} + dev: true + /dayjs@1.11.10: resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} dev: true @@ -6533,8 +6560,8 @@ packages: escape-string-regexp: 1.0.5 dev: true - /figures@6.0.1: - resolution: {integrity: sha512-0oY/olScYD4IhQ8u//gCPA4F3mlTn2dacYmiDm/mbDQvpmLjV4uH+zhsQ5IyXRyvqkvtUkXkNdGvg5OFJTCsuQ==} + /figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} engines: {node: '>=18'} dependencies: is-unicode-supported: 2.0.0 @@ -8054,7 +8081,7 @@ packages: react: 18.2.0 dev: true - /marked-terminal@7.0.0(marked@12.0.0): + /marked-terminal@7.0.0(marked@12.0.1): resolution: {integrity: sha512-sNEx8nn9Ktcm6pL0TnRz8tnXq/mSS0Q1FRSwJOAqw4lAB4l49UeDf85Gm1n9RPFm5qurCPjwi1StAQT2XExhZw==} engines: {node: '>=16.0.0'} peerDependencies: @@ -8064,13 +8091,13 @@ packages: chalk: 5.3.0 cli-highlight: 2.1.11 cli-table3: 0.6.3 - marked: 12.0.0 + marked: 12.0.1 node-emoji: 2.1.3 supports-hyperlinks: 3.0.0 dev: true - /marked@12.0.0: - resolution: {integrity: sha512-Vkwtq9rLqXryZnWaQc86+FHLC6tr/fycMfYAhiOIXkrNmeGAyhSxjqu0Rs1i0bBqw5u0S7+lV9fdH2ZSVaoa0w==} + /marked@12.0.1: + resolution: {integrity: sha512-Y1/V2yafOcOdWQCX0XpAKXzDakPOpn6U0YLxTJs3cww6VxOzZV1BTOOYWLvH3gX38cq+iLwljHHTnMtlDfg01Q==} engines: {node: '>= 18'} hasBin: true dev: true @@ -8355,8 +8382,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /normalize-url@8.0.0: - resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==} + /normalize-url@8.0.1: + resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==} engines: {node: '>=14.16'} dev: true @@ -8374,8 +8401,8 @@ packages: path-key: 4.0.0 dev: true - /npm@10.4.0: - resolution: {integrity: sha512-RS7Mx0OVfXlOcQLRePuDIYdFCVBPCNapWHplDK+mh7GDdP/Tvor4ocuybRRPSvfcRb2vjRJt1fHCqw3cr8qACQ==} + /npm@10.5.0: + resolution: {integrity: sha512-Ejxwvfh9YnWVU2yA5FzoYLTW52vxHCz+MHrOFg9Cc8IFgF/6f5AGPAvb5WTay5DIUP1NIfN3VBZ0cLlGO0Ys+A==} engines: {node: ^18.17.0 || >=20.5.0} hasBin: true dev: true @@ -8739,7 +8766,7 @@ packages: dependencies: '@babel/code-frame': 7.23.5 index-to-position: 0.1.2 - type-fest: 4.10.3 + type-fest: 4.12.0 dev: true /parse5-htmlparser2-tree-adapter@6.0.1: @@ -9328,7 +9355,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /rc-picker@4.0.0-alpha.44(dayjs@1.11.10)(react-dom@18.2.0)(react@18.2.0): + /rc-picker@4.0.0-alpha.44(date-fns@3.4.0)(dayjs@1.11.10)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-OvzzTS4UZDT1qRfv4PRK/+LDpXWJ6sD0zv5LPC7fvprihT/YVvjrOQPicWLlw5GqrrqP4hqbQkWB4KXDNlb5ag==} engines: {node: '>=8.x'} peerDependencies: @@ -9351,6 +9378,7 @@ packages: '@babel/runtime': 7.23.9 '@rc-component/trigger': 1.18.3(react-dom@18.2.0)(react@18.2.0) classnames: 2.5.1 + date-fns: 3.4.0 dayjs: 1.11.10 rc-overflow: 1.3.2(react-dom@18.2.0)(react@18.2.0) rc-resize-observer: 1.4.0(react-dom@18.2.0)(react@18.2.0) @@ -9359,6 +9387,37 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true + /rc-picker@4.3.0(date-fns@3.4.0)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-bQNB/+NdW55jlQ5lPnNqF5J90Tq4SihLbAF7tzPBvGDJyoYmDgwLm4FN0ZB3Ot9i1v6vJY/1mgqZZTT9jbYc5w==} + engines: {node: '>=8.x'} + peerDependencies: + date-fns: '>= 2.x' + dayjs: '>= 1.x' + luxon: '>= 3.x' + moment: '>= 2.x' + react: '>=16.9.0' + react-dom: '>=16.9.0' + peerDependenciesMeta: + date-fns: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + dependencies: + '@babel/runtime': 7.23.9 + '@rc-component/trigger': 2.0.0(react-dom@18.2.0)(react@18.2.0) + classnames: 2.5.1 + date-fns: 3.4.0 + rc-overflow: 1.3.2(react-dom@18.2.0)(react@18.2.0) + rc-resize-observer: 1.4.0(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.38.1(react-dom@18.2.0)(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + /rc-progress@3.5.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-V6Amx6SbLRwPin/oD+k1vbPrO8+9Qf8zW1T8A7o83HdNafEVvAxPV5YsgtKFP+Ud5HghLj33zKOcEHrcrUGkfw==} peerDependencies: @@ -9773,7 +9832,7 @@ packages: dependencies: find-up-simple: 1.0.0 read-pkg: 9.0.1 - type-fest: 4.10.3 + type-fest: 4.12.0 dev: true /read-pkg-up@7.0.1: @@ -9802,7 +9861,7 @@ packages: '@types/normalize-package-data': 2.4.4 normalize-package-data: 6.0.0 parse-json: 8.1.0 - type-fest: 4.10.3 + type-fest: 4.12.0 unicorn-magic: 0.1.0 dev: true @@ -10124,14 +10183,14 @@ packages: '@semantic-release/commit-analyzer': 11.1.0(semantic-release@23.0.2) '@semantic-release/error': 4.0.0 '@semantic-release/github': 9.2.6(semantic-release@23.0.2) - '@semantic-release/npm': 11.0.2(semantic-release@23.0.2) + '@semantic-release/npm': 11.0.3(semantic-release@23.0.2) '@semantic-release/release-notes-generator': 12.1.0(semantic-release@23.0.2) aggregate-error: 5.0.0 cosmiconfig: 9.0.0(typescript@5.3.3) debug: 4.3.4 env-ci: 11.0.0 execa: 8.0.1 - figures: 6.0.1 + figures: 6.1.0 find-versions: 5.1.0 get-stream: 6.0.1 git-log-parser: 1.2.0 @@ -10139,8 +10198,8 @@ packages: hosted-git-info: 7.0.1 import-from-esm: 1.3.3 lodash-es: 4.17.21 - marked: 12.0.0 - marked-terminal: 7.0.0(marked@12.0.0) + marked: 12.0.1 + marked-terminal: 7.0.0(marked@12.0.1) micromatch: 4.0.5 p-each-series: 3.0.0 p-reduce: 3.0.0 @@ -10900,8 +10959,8 @@ packages: engines: {node: '>=14.16'} dev: true - /type-fest@4.10.3: - resolution: {integrity: sha512-JLXyjizi072smKGGcZiAJDCNweT8J+AuRxmPZ1aG7TERg4ijx9REl8CNhbr36RV4qXqL1gO1FF9HL8OkVmmrsA==} + /type-fest@4.12.0: + resolution: {integrity: sha512-5Y2/pp2wtJk8o08G0CMkuFPCO354FGwk/vbidxrdhRGZfd0tFnb4Qb8anp9XxXriwBgVPjdWbKpGl4J9lJY2jQ==} engines: {node: '>=16'} dev: true diff --git a/src/controls/DatetimeControl.test.tsx b/src/controls/DatetimeControl.test.tsx new file mode 100644 index 0000000..5f88920 --- /dev/null +++ b/src/controls/DatetimeControl.test.tsx @@ -0,0 +1,34 @@ +import { describe, expect, test, it } from "vitest" +import { render } from "../common/test-render" + +import { screen } from "@testing-library/react" +import { datetimeSchema, datetimeUISchema, datetimeUISchemaWithRule } from "../testSchemas/datetimeSchema" + +describe("DatetimeControl", () => { + const timestamp = "2023-07-18T01:02:01.182Z" + const title = "The Future is Now" + test("renders a datetime input with no UISchema provided", () => { + render({ + schema: datetimeSchema, + }) + expect(screen.getByText(title)).not.toBeNull() + }) + + it("Follows the hide rule", () => { + render({ + data: timestamp, + schema: datetimeSchema, + uischema: datetimeUISchemaWithRule, + }) + expect(screen.queryByText(title)).toBeNull() + }) + + it("renders when data is included", () => { + render({ + data: timestamp, + schema: datetimeSchema, + uischema: datetimeUISchema, + }) + expect(screen.getByText(title)).not.toBeNull() + }) +}) diff --git a/src/controls/DatetimeControl.tsx b/src/controls/DatetimeControl.tsx new file mode 100644 index 0000000..8663d6f --- /dev/null +++ b/src/controls/DatetimeControl.tsx @@ -0,0 +1,21 @@ +import { ControlProps } from "@jsonforms/core" +import { DatePicker, Form } from "antd" +import dateFnsGenerateConfig from "rc-picker/lib/generate/dateFns" + + +interface DatetimeControlProps extends ControlProps { + data: string + handleChange(path: string, value: Date | null): void + path: string +} + +const MyDatePicker = DatePicker.generatePicker(dateFnsGenerateConfig) + +export function DatetimeControl({ data, handleChange, path, label, visible, id }: DatetimeControlProps) { + const dateFormat = "MM/DD/YYYY" + return !visible ? null : ( + + handleChange(path, e)} /> + + ) +} diff --git a/src/renderers.ts b/src/renderers.ts index ff1d8fa..6f05680 100644 --- a/src/renderers.ts +++ b/src/renderers.ts @@ -1,3 +1,5 @@ +import React from "react"; + import { JsonFormsRendererRegistryEntry, JsonFormsCellRendererRegistryEntry, @@ -9,6 +11,7 @@ import { isLayout, not, and, + isDateTimeControl, } from "@jsonforms/core"; import { withJsonFormsControlProps, @@ -25,7 +28,7 @@ import { UnknownControl } from "./controls/UnknownControl"; import { VerticalLayoutRenderer } from "./layouts/VerticalLayoutRenderer"; import { ObjectControl } from "./controls/ObjectControl"; import { GroupLayoutRenderer } from "./layouts/GroupLayoutRenderer"; -import React from "react"; +import { DatetimeControl } from "./controls/DatetimeControl"; // Ordered from lowest rank to highest rank. Higher rank renderers will be preferred over lower rank renderers. export const rendererRegistryEntries: JsonFormsRendererRegistryEntry[] = [ @@ -53,12 +56,19 @@ export const rendererRegistryEntries: JsonFormsRendererRegistryEntry[] = [ tester: rankWith(2, uiTypeIs("Label")), renderer: withJsonFormsLabelProps(AlertControl), }, + { + tester: rankWith(2, isDateTimeControl), + renderer: withJsonFormsControlProps(DatetimeControl) + }, { tester: rankWith(10, and(isObjectControl, not(isLayout))), renderer: withJsonFormsDetailProps(ObjectControl), }, ]; + + + export const cellRegistryEntries: JsonFormsCellRendererRegistryEntry[] = [ { tester: rankWith(1, () => true), diff --git a/src/testSchemas/datetimeSchema.ts b/src/testSchemas/datetimeSchema.ts new file mode 100644 index 0000000..481c97e --- /dev/null +++ b/src/testSchemas/datetimeSchema.ts @@ -0,0 +1,36 @@ +export const sampleDatetimeSchema = { + title: "The Future is Now", + type: "string", + format: "date-time", +} as const + +export const datetimeSchema = { + title: "The Future is Now", + type: "string", + format: "date-time", + scope: "#/properties/The Future is Now", +} as const + +export const datetimeUISchema = { + type: "VerticalLayout", + elements: [ + { + type: "Control", + scope: "#", + }, + ], +} as const + +export const datetimeUISchemaWithRule = { + type: "VerticalLayout", + elements: [ + { + type: "Control", + scope: "#", + rule: { + effect: "HIDE", + condition: {}, + }, + }, + ], +} as const From ec4b059d2105006b56d4629463614af7d59201fa Mon Sep 17 00:00:00 2001 From: Thu Pham Date: Thu, 7 Mar 2024 22:57:59 -0800 Subject: [PATCH 02/14] Try what Nathan suggested --- src/controls/DatetimeControl.test.tsx | 10 ++++----- src/testSchemas/datetimeSchema.ts | 31 ++++++++++++++++----------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/controls/DatetimeControl.test.tsx b/src/controls/DatetimeControl.test.tsx index 5f88920..6026eca 100644 --- a/src/controls/DatetimeControl.test.tsx +++ b/src/controls/DatetimeControl.test.tsx @@ -16,7 +16,7 @@ describe("DatetimeControl", () => { it("Follows the hide rule", () => { render({ - data: timestamp, + data: {datetime: timestamp}, schema: datetimeSchema, uischema: datetimeUISchemaWithRule, }) @@ -25,10 +25,10 @@ describe("DatetimeControl", () => { it("renders when data is included", () => { render({ - data: timestamp, + data: { datetime: timestamp }, schema: datetimeSchema, uischema: datetimeUISchema, - }) - expect(screen.getByText(title)).not.toBeNull() - }) + }); + expect(screen.getByText(title)).not.toBeNull(); + }); }) diff --git a/src/testSchemas/datetimeSchema.ts b/src/testSchemas/datetimeSchema.ts index 481c97e..92ac943 100644 --- a/src/testSchemas/datetimeSchema.ts +++ b/src/testSchemas/datetimeSchema.ts @@ -1,15 +1,20 @@ -export const sampleDatetimeSchema = { - title: "The Future is Now", - type: "string", - format: "date-time", -} as const +import { JSONSchema } from "json-schema-to-ts" +import { UISchema } from "../ui-schema" +import { RuleEffect } from "@jsonforms/core" + export const datetimeSchema = { - title: "The Future is Now", - type: "string", - format: "date-time", - scope: "#/properties/The Future is Now", -} as const + type: "object", + properties: { + datetime: { + type: "string", + title: "The Future is Now", + format: "date-time", + }, + }, + required: ["datetime"], +} satisfies JSONSchema + export const datetimeUISchema = { type: "VerticalLayout", @@ -19,7 +24,7 @@ export const datetimeUISchema = { scope: "#", }, ], -} as const +} satisfies UISchema export const datetimeUISchemaWithRule = { type: "VerticalLayout", @@ -28,9 +33,9 @@ export const datetimeUISchemaWithRule = { type: "Control", scope: "#", rule: { - effect: "HIDE", + effect: RuleEffect.HIDE, condition: {}, }, }, ], -} as const +} satisfies UISchema \ No newline at end of file From 0c46a1736f6d018e09b54074d6fb336cc65dfe34 Mon Sep 17 00:00:00 2001 From: Thu Pham Date: Thu, 7 Mar 2024 23:34:26 -0800 Subject: [PATCH 03/14] Got tests passing, storybook WIP --- .../controls/DatetimeControl.stories.tsx | 33 +++++++++++++++++++ src/testSchemas/datetimeSchema.ts | 4 +-- 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 src/stories/controls/DatetimeControl.stories.tsx diff --git a/src/stories/controls/DatetimeControl.stories.tsx b/src/stories/controls/DatetimeControl.stories.tsx new file mode 100644 index 0000000..a4f286c --- /dev/null +++ b/src/stories/controls/DatetimeControl.stories.tsx @@ -0,0 +1,33 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { rendererRegistryEntries } from "../../renderers"; +import { StorybookAntDJsonForm } from "../../common/StorybookAntDJsonForm"; +import { datetimeSchema, datetimeUISchema } from "../../testSchemas/datetimeSchema"; + +const meta: Meta = { + title: "Control/Datetime", + component: StorybookAntDJsonForm, + tags: ["autodocs"], + args: { + jsonSchema: datetimeSchema, + rendererRegistryEntries: [ + ...rendererRegistryEntries, + ] + }, + argTypes: { + rendererRegistryEntries: {}, + jsonSchema: { + control: "object", + } + } +}; + +export default meta; +type Story = StoryObj; + +export const Datetime: Story = { + tags: ["autodocs"], + args: { + jsonSchema: datetimeSchema, + // uiSchema: datetimeUISchema, + }, +} diff --git a/src/testSchemas/datetimeSchema.ts b/src/testSchemas/datetimeSchema.ts index 92ac943..955c275 100644 --- a/src/testSchemas/datetimeSchema.ts +++ b/src/testSchemas/datetimeSchema.ts @@ -21,7 +21,7 @@ export const datetimeUISchema = { elements: [ { type: "Control", - scope: "#", + scope: "#/properties/datetime", }, ], } satisfies UISchema @@ -31,7 +31,7 @@ export const datetimeUISchemaWithRule = { elements: [ { type: "Control", - scope: "#", + scope: "#/properties/datetime", rule: { effect: RuleEffect.HIDE, condition: {}, From 576db4b522b4b433d759a94b5667ee251ca7591d Mon Sep 17 00:00:00 2001 From: Thu Pham Date: Thu, 7 Mar 2024 23:44:09 -0800 Subject: [PATCH 04/14] WIP --- src/renderers.ts | 5 +---- src/stories/controls/DatetimeControl.stories.tsx | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/renderers.ts b/src/renderers.ts index 6f05680..7668c2e 100644 --- a/src/renderers.ts +++ b/src/renderers.ts @@ -58,7 +58,7 @@ export const rendererRegistryEntries: JsonFormsRendererRegistryEntry[] = [ }, { tester: rankWith(2, isDateTimeControl), - renderer: withJsonFormsControlProps(DatetimeControl) + renderer: withJsonFormsControlProps(DatetimeControl), }, { tester: rankWith(10, and(isObjectControl, not(isLayout))), @@ -66,9 +66,6 @@ export const rendererRegistryEntries: JsonFormsRendererRegistryEntry[] = [ }, ]; - - - export const cellRegistryEntries: JsonFormsCellRendererRegistryEntry[] = [ { tester: rankWith(1, () => true), diff --git a/src/stories/controls/DatetimeControl.stories.tsx b/src/stories/controls/DatetimeControl.stories.tsx index a4f286c..91ab6d8 100644 --- a/src/stories/controls/DatetimeControl.stories.tsx +++ b/src/stories/controls/DatetimeControl.stories.tsx @@ -1,7 +1,8 @@ import { Meta, StoryObj } from "@storybook/react"; -import { rendererRegistryEntries } from "../../renderers"; +import { cellRegistryEntries, rendererRegistryEntries } from "../../renderers"; import { StorybookAntDJsonForm } from "../../common/StorybookAntDJsonForm"; import { datetimeSchema, datetimeUISchema } from "../../testSchemas/datetimeSchema"; +import { JsonForms } from "@jsonforms/react"; const meta: Meta = { title: "Control/Datetime", @@ -28,6 +29,17 @@ export const Datetime: Story = { tags: ["autodocs"], args: { jsonSchema: datetimeSchema, - // uiSchema: datetimeUISchema, + uiSchema: datetimeUISchema, }, } + +export const DateTimeControl: Story = { + render: () => ( + + ), +} \ No newline at end of file From fbece4d642f59f4e8ef8bbf9a1e58cdbf6674a1e Mon Sep 17 00:00:00 2001 From: Thu Pham Date: Fri, 8 Mar 2024 09:35:30 -0800 Subject: [PATCH 05/14] More WIP and debugging --- src/controls/DatetimeControl.test.tsx | 17 ++++++++ .../controls/DatetimeControl.stories.tsx | 39 +++++++++++++++++-- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/controls/DatetimeControl.test.tsx b/src/controls/DatetimeControl.test.tsx index 6026eca..3c4d4c0 100644 --- a/src/controls/DatetimeControl.test.tsx +++ b/src/controls/DatetimeControl.test.tsx @@ -3,7 +3,24 @@ import { render } from "../common/test-render" import { screen } from "@testing-library/react" import { datetimeSchema, datetimeUISchema, datetimeUISchemaWithRule } from "../testSchemas/datetimeSchema" +import { isDateTimeControl, rankWith } from "@jsonforms/core" +describe("DatetimeControlTester", () => { + test("tester works", () => { + const uiSchema = { + type: "Control", + scope: "#/properties/datetime", + } + const schema = { + type: "string", + title: "The Future is Now", + format: "date-time", + } + const context = {rootSchema: datetimeSchema, config: {}} + + expect(rankWith(1, isDateTimeControl)(uiSchema, schema, context)).toBe(1) + }) +}) describe("DatetimeControl", () => { const timestamp = "2023-07-18T01:02:01.182Z" const title = "The Future is Now" diff --git a/src/stories/controls/DatetimeControl.stories.tsx b/src/stories/controls/DatetimeControl.stories.tsx index 91ab6d8..915b619 100644 --- a/src/stories/controls/DatetimeControl.stories.tsx +++ b/src/stories/controls/DatetimeControl.stories.tsx @@ -3,6 +3,7 @@ import { cellRegistryEntries, rendererRegistryEntries } from "../../renderers"; import { StorybookAntDJsonForm } from "../../common/StorybookAntDJsonForm"; import { datetimeSchema, datetimeUISchema } from "../../testSchemas/datetimeSchema"; import { JsonForms } from "@jsonforms/react"; +import { DatetimeControl } from "../../controls/DatetimeControl"; const meta: Meta = { title: "Control/Datetime", @@ -15,10 +16,14 @@ const meta: Meta = { ] }, argTypes: { - rendererRegistryEntries: {}, + rendererRegistryEntries: { table: { disable: true } }, + uiSchemaRegistryEntries: { table: { disable: true } }, jsonSchema: { control: "object", - } + }, + data: {table: {disable: true}}, + config: {control: "object"}, + onChange: {table: {disable: true, action: "on-change"}}, } }; @@ -33,7 +38,7 @@ export const Datetime: Story = { }, } -export const DateTimeControl: Story = { +export const DateTimeControlUsingJsonForms: Story = { render: () => ( ), +} + +export const DateTimeControlComponent: Story = { + argTypes: { + rendererRegistryEntries: { table: { disable: true } }, + uiSchemaRegistryEntries: { table: { disable: true } }, + jsonSchema: { + control: "object", + }, + data: {table: {disable: true}}, + config: {control: "object"}, + onChange: {table: {disable: true, action: "on-change"}}, + }, + render: () => ( + console.log(result)} + label="Datetime" + uischema={datetimeUISchema["elements"][0]} + errors="" + rootSchema={{}} + id="" + enabled={true} + visible={true} + /> + ), } \ No newline at end of file From 78742fa0e3aa0d7bd82982c5f0ff10d05a5ce408 Mon Sep 17 00:00:00 2001 From: Thu Pham Date: Wed, 20 Mar 2024 16:01:04 -0700 Subject: [PATCH 06/14] Getting Datetime to work --- package.json | 8 +- src/controls/DatetimeControl.test.tsx | 22 +++--- src/controls/DatetimeControl.tsx | 19 ++++- src/renderer-registry-entries.ts | 6 ++ .../controls/DatetimeControl.stories.tsx | 74 +++++-------------- src/testSchemas/datetimeSchema.ts | 4 +- 6 files changed, 59 insertions(+), 74 deletions(-) diff --git a/package.json b/package.json index aafc2f0..79b80b9 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,9 @@ "name": "@great-expectations/jsonforms-antd-renderers", "private": false, "version": "0.0.0-semantic-release", - "files": ["lib/**/*"], + "files": [ + "lib/**/*" + ], "main": "./lib/cjs/index.js", "types": "./lib/cjs/index.d.ts", "exports": { @@ -21,7 +23,9 @@ "access": "public" }, "release": { - "branches": ["main"] + "branches": [ + "main" + ] }, "repository": { "type": "git", diff --git a/src/controls/DatetimeControl.test.tsx b/src/controls/DatetimeControl.test.tsx index 3c4d4c0..4984c5e 100644 --- a/src/controls/DatetimeControl.test.tsx +++ b/src/controls/DatetimeControl.test.tsx @@ -2,7 +2,11 @@ import { describe, expect, test, it } from "vitest" import { render } from "../common/test-render" import { screen } from "@testing-library/react" -import { datetimeSchema, datetimeUISchema, datetimeUISchemaWithRule } from "../testSchemas/datetimeSchema" +import { + datetimeSchema, + datetimeUISchema, + datetimeUISchemaWithRule, +} from "../testSchemas/datetimeSchema" import { isDateTimeControl, rankWith } from "@jsonforms/core" describe("DatetimeControlTester", () => { @@ -16,7 +20,7 @@ describe("DatetimeControlTester", () => { title: "The Future is Now", format: "date-time", } - const context = {rootSchema: datetimeSchema, config: {}} + const context = { rootSchema: datetimeSchema, config: {} } expect(rankWith(1, isDateTimeControl)(uiSchema, schema, context)).toBe(1) }) @@ -24,28 +28,28 @@ describe("DatetimeControlTester", () => { describe("DatetimeControl", () => { const timestamp = "2023-07-18T01:02:01.182Z" const title = "The Future is Now" - test("renders a datetime input with no UISchema provided", () => { + test("renders a datetime input with no UISchema provided", async () => { render({ schema: datetimeSchema, }) - expect(screen.getByText(title)).not.toBeNull() + await screen.findByText(title) }) it("Follows the hide rule", () => { render({ - data: {datetime: timestamp}, + data: { datetime: timestamp }, schema: datetimeSchema, uischema: datetimeUISchemaWithRule, }) expect(screen.queryByText(title)).toBeNull() }) - it("renders when data is included", () => { + it("renders when data is included", async () => { render({ data: { datetime: timestamp }, schema: datetimeSchema, uischema: datetimeUISchema, - }); - expect(screen.getByText(title)).not.toBeNull(); - }); + }) + await screen.findByText(title) + }) }) diff --git a/src/controls/DatetimeControl.tsx b/src/controls/DatetimeControl.tsx index 8663d6f..9cd53b8 100644 --- a/src/controls/DatetimeControl.tsx +++ b/src/controls/DatetimeControl.tsx @@ -1,8 +1,8 @@ import { ControlProps } from "@jsonforms/core" +import { withJsonFormsControlProps } from "@jsonforms/react" import { DatePicker, Form } from "antd" import dateFnsGenerateConfig from "rc-picker/lib/generate/dateFns" - interface DatetimeControlProps extends ControlProps { data: string handleChange(path: string, value: Date | null): void @@ -11,11 +11,24 @@ interface DatetimeControlProps extends ControlProps { const MyDatePicker = DatePicker.generatePicker(dateFnsGenerateConfig) -export function DatetimeControl({ data, handleChange, path, label, visible, id }: DatetimeControlProps) { +export function DatetimeControl({ + data, + handleChange, + path, + label, + visible, + id, +}: DatetimeControlProps) { const dateFormat = "MM/DD/YYYY" return !visible ? null : ( - handleChange(path, e)} /> + handleChange(path, e)} + /> ) } + +export const DatetimeRenderer = withJsonFormsControlProps(DatetimeControl) diff --git a/src/renderer-registry-entries.ts b/src/renderer-registry-entries.ts index 44afce3..190ed3a 100644 --- a/src/renderer-registry-entries.ts +++ b/src/renderer-registry-entries.ts @@ -18,6 +18,7 @@ import { and, or, isOneOfControl, + isDateTimeControl, } from "@jsonforms/core" import { withJsonFormsCellProps } from "@jsonforms/react" @@ -33,6 +34,7 @@ import { NumericRenderer } from "./controls/NumericControl" import { NumericSliderRenderer } from "./controls/NumericSliderControl" import { OneOfRenderer } from "./controls/combinators/OneOfControl" import { ObjectArrayRenderer } from "./controls/ObjectArrayControl" +import { DatetimeRenderer } from "./controls/DatetimeControl" // Ordered from lowest rank to highest rank. Higher rank renderers will be preferred over lower rank renderers. export const rendererRegistryEntries: JsonFormsRendererRegistryEntry[] = [ @@ -68,6 +70,10 @@ export const rendererRegistryEntries: JsonFormsRendererRegistryEntry[] = [ tester: rankWith(2, or(isNumberControl, isIntegerControl)), renderer: NumericRenderer, }, + { + tester: rankWith(3, isDateTimeControl), + renderer: DatetimeRenderer, + }, { tester: rankWith( 3, diff --git a/src/stories/controls/DatetimeControl.stories.tsx b/src/stories/controls/DatetimeControl.stories.tsx index 915b619..573bae8 100644 --- a/src/stories/controls/DatetimeControl.stories.tsx +++ b/src/stories/controls/DatetimeControl.stories.tsx @@ -1,9 +1,10 @@ -import { Meta, StoryObj } from "@storybook/react"; -import { cellRegistryEntries, rendererRegistryEntries } from "../../renderers"; -import { StorybookAntDJsonForm } from "../../common/StorybookAntDJsonForm"; -import { datetimeSchema, datetimeUISchema } from "../../testSchemas/datetimeSchema"; -import { JsonForms } from "@jsonforms/react"; -import { DatetimeControl } from "../../controls/DatetimeControl"; +import { Meta, StoryObj } from "@storybook/react" +import { rendererRegistryEntries } from "../../renderer-registry-entries" +import { StorybookAntDJsonForm } from "../../common/StorybookAntDJsonForm" +import { + datetimeSchema, + datetimeUISchema, +} from "../../testSchemas/datetimeSchema" const meta: Meta = { title: "Control/Datetime", @@ -11,9 +12,7 @@ const meta: Meta = { tags: ["autodocs"], args: { jsonSchema: datetimeSchema, - rendererRegistryEntries: [ - ...rendererRegistryEntries, - ] + rendererRegistryEntries: [...rendererRegistryEntries], }, argTypes: { rendererRegistryEntries: { table: { disable: true } }, @@ -21,58 +20,19 @@ const meta: Meta = { jsonSchema: { control: "object", }, - data: {table: {disable: true}}, - config: {control: "object"}, - onChange: {table: {disable: true, action: "on-change"}}, - } -}; + data: { table: { disable: true } }, + config: { control: "object" }, + onChange: { table: { disable: true, action: "on-change" } }, + }, +} -export default meta; -type Story = StoryObj; +export default meta +type Story = StoryObj export const Datetime: Story = { tags: ["autodocs"], - args: { - jsonSchema: datetimeSchema, + args: { + jsonSchema: datetimeSchema, uiSchema: datetimeUISchema, }, } - -export const DateTimeControlUsingJsonForms: Story = { - render: () => ( - - ), -} - -export const DateTimeControlComponent: Story = { - argTypes: { - rendererRegistryEntries: { table: { disable: true } }, - uiSchemaRegistryEntries: { table: { disable: true } }, - jsonSchema: { - control: "object", - }, - data: {table: {disable: true}}, - config: {control: "object"}, - onChange: {table: {disable: true, action: "on-change"}}, - }, - render: () => ( - console.log(result)} - label="Datetime" - uischema={datetimeUISchema["elements"][0]} - errors="" - rootSchema={{}} - id="" - enabled={true} - visible={true} - /> - ), -} \ No newline at end of file diff --git a/src/testSchemas/datetimeSchema.ts b/src/testSchemas/datetimeSchema.ts index 955c275..7b22b7a 100644 --- a/src/testSchemas/datetimeSchema.ts +++ b/src/testSchemas/datetimeSchema.ts @@ -2,7 +2,6 @@ import { JSONSchema } from "json-schema-to-ts" import { UISchema } from "../ui-schema" import { RuleEffect } from "@jsonforms/core" - export const datetimeSchema = { type: "object", properties: { @@ -15,7 +14,6 @@ export const datetimeSchema = { required: ["datetime"], } satisfies JSONSchema - export const datetimeUISchema = { type: "VerticalLayout", elements: [ @@ -38,4 +36,4 @@ export const datetimeUISchemaWithRule = { }, }, ], -} satisfies UISchema \ No newline at end of file +} satisfies UISchema From 9a59b853630c7769eadf2dd34b4da9a3083599d9 Mon Sep 17 00:00:00 2001 From: Thu Pham Date: Wed, 20 Mar 2024 16:05:34 -0700 Subject: [PATCH 07/14] Make required work with datetime --- src/controls/DatetimeControl.tsx | 3 ++- src/stories/controls/DatetimeControl.stories.tsx | 11 +++++++++++ src/testSchemas/datetimeSchema.ts | 1 - 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/controls/DatetimeControl.tsx b/src/controls/DatetimeControl.tsx index 9cd53b8..ab249c4 100644 --- a/src/controls/DatetimeControl.tsx +++ b/src/controls/DatetimeControl.tsx @@ -18,10 +18,11 @@ export function DatetimeControl({ label, visible, id, + required, }: DatetimeControlProps) { const dateFormat = "MM/DD/YYYY" return !visible ? null : ( - + Date: Wed, 20 Mar 2024 16:17:39 -0700 Subject: [PATCH 08/14] format --- src/renderer-registry-entries.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/renderer-registry-entries.ts b/src/renderer-registry-entries.ts index ac1101e..9997fc6 100644 --- a/src/renderer-registry-entries.ts +++ b/src/renderer-registry-entries.ts @@ -40,7 +40,6 @@ import { import { OneOfRenderer } from "./controls/combinators/OneOfControl" import { DatetimeRenderer } from "./controls/DatetimeControl" - // Ordered from lowest rank to highest rank. Higher rank renderers will be preferred over lower rank renderers. export const rendererRegistryEntries: JsonFormsRendererRegistryEntry[] = [ { From c7544901b00ec1cbfa0729a859cbe0b11c9a8d9f Mon Sep 17 00:00:00 2001 From: Thu Pham Date: Wed, 27 Mar 2024 16:35:11 -0700 Subject: [PATCH 09/14] Should use deps instead of peerdeps --- package.json | 14 +++++--------- pnpm-lock.yaml | 32 ++++++++------------------------ 2 files changed, 13 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 79b80b9..06021f4 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,7 @@ "name": "@great-expectations/jsonforms-antd-renderers", "private": false, "version": "0.0.0-semantic-release", - "files": [ - "lib/**/*" - ], + "files": ["lib/**/*"], "main": "./lib/cjs/index.js", "types": "./lib/cjs/index.d.ts", "exports": { @@ -23,9 +21,7 @@ "access": "public" }, "release": { - "branches": [ - "main" - ] + "branches": ["main"] }, "repository": { "type": "git", @@ -52,8 +48,6 @@ "@jsonforms/core": "^3.2.1", "@jsonforms/react": "^3.2.1", "antd": "^5.14.0", - "date-fns": "^3.3.1", - "rc-picker": "^4.2.0", "react": "^17 || ^18" }, "devDependencies": { @@ -104,6 +98,8 @@ "lodash.isempty": "^4.4.0", "lodash.merge": "^4.6.2", "lodash.range": "^3.2.0", - "lodash.startcase": "^4.4.0" + "lodash.startcase": "^4.4.0", + "date-fns": "^3.3.1", + "rc-picker": "^4.2.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2a75765..bf26825 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false dependencies: + date-fns: + specifier: ^3.3.1 + version: 3.6.0 lodash.isempty: specifier: ^4.4.0 version: 4.4.0 @@ -17,6 +20,9 @@ dependencies: lodash.startcase: specifier: ^4.4.0 version: 4.4.0 + rc-picker: + specifier: ^4.2.0 + version: 4.3.0(date-fns@3.6.0)(react-dom@18.2.0)(react@18.2.0) devDependencies: '@ant-design/icons': @@ -91,9 +97,6 @@ devDependencies: antd: specifier: ^5.14.0 version: 5.14.0(date-fns@3.6.0)(react-dom@18.2.0)(react@18.2.0) - date-fns: - specifier: ^3.3.1 - version: 3.6.0 eslint: specifier: ^8.55.0 version: 8.56.0 @@ -121,9 +124,6 @@ devDependencies: prettier: specifier: 3.2.5 version: 3.2.5 - rc-picker: - specifier: ^4.2.0 - version: 4.3.0(date-fns@3.6.0)(react-dom@18.2.0)(react@18.2.0) react: specifier: ^18.2.0 version: 18.2.0 @@ -1484,7 +1484,6 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.1 - dev: true /@babel/template@7.24.0: resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} @@ -2988,7 +2987,6 @@ packages: rc-util: 5.38.1(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - dev: true /@rc-component/tour@1.12.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-U4mf1FiUxGCwrX4ed8op77Y8VKur+8Y/61ylxtqGbcSoh1EBC7bWd/DkLu0ClTUrKZInqEi1FL7YgFtnT90vHA==} @@ -3038,7 +3036,7 @@ packages: rc-util: 5.38.1(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - dev: true + dev: false /@rollup/pluginutils@5.1.0: resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} @@ -5529,7 +5527,6 @@ packages: /classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} - dev: true /clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} @@ -5843,7 +5840,6 @@ packages: /date-fns@3.6.0: resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} - dev: true /dayjs@1.11.10: resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} @@ -7832,7 +7828,6 @@ packages: /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} @@ -8156,7 +8151,6 @@ packages: hasBin: true dependencies: js-tokens: 4.0.0 - dev: true /loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} @@ -9472,7 +9466,6 @@ packages: rc-util: 5.38.1(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - dev: true /rc-notification@5.3.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-WCf0uCOkZ3HGfF0p1H4Sgt7aWfipxORWTPp7o6prA3vxwtWhtug3GfpYls1pnBp4WA+j8vGIi5c2/hQRpGzPcQ==} @@ -9501,7 +9494,6 @@ packages: rc-util: 5.38.1(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - dev: true /rc-pagination@4.0.4(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-GGrLT4NgG6wgJpT/hHIpL9nELv27A1XbSZzECIuQBQTVSf4xGKxWr6I/jhpRPauYEWEbWVw22ObG6tJQqwJqWQ==} @@ -9577,7 +9569,7 @@ packages: rc-util: 5.38.1(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - dev: true + dev: false /rc-progress@3.5.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-V6Amx6SbLRwPin/oD+k1vbPrO8+9Qf8zW1T8A7o83HdNafEVvAxPV5YsgtKFP+Ud5HghLj33zKOcEHrcrUGkfw==} @@ -9618,7 +9610,6 @@ packages: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) resize-observer-polyfill: 1.5.1 - dev: true /rc-segmented@2.3.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-I3FtM5Smua/ESXutFfb8gJ8ZPcvFR+qUgeeGFQHBOvRiRKyAk4aBE5nfqrxXx+h8/vn60DQjOt6i4RNtrbOobg==} @@ -9810,7 +9801,6 @@ packages: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-is: 18.2.0 - dev: true /rc-virtual-list@3.11.4(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-NbBi0fvyIu26gP69nQBiWgUMTPX3mr4FcuBQiVqagU0BnuX8WQkiivnMs105JROeuUIFczLrlgUhLQwTWV1XDA==} @@ -9891,7 +9881,6 @@ packages: loose-envify: 1.4.0 react: 18.2.0 scheduler: 0.23.0 - dev: true /react-element-to-jsx-string@15.0.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==} @@ -9920,7 +9909,6 @@ packages: /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - dev: true /react-refresh@0.14.0: resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} @@ -9984,7 +9972,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: loose-envify: 1.4.0 - dev: true /read-pkg-up@11.0.0: resolution: {integrity: sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==} @@ -10099,7 +10086,6 @@ packages: /regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - dev: true /regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} @@ -10181,7 +10167,6 @@ packages: /resize-observer-polyfill@1.5.1: resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} - dev: true /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} @@ -10328,7 +10313,6 @@ packages: resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} dependencies: loose-envify: 1.4.0 - dev: true /scroll-into-view-if-needed@3.1.0: resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} From 731d1ac3bf6f9f47383ad9542a60e66698697a07 Mon Sep 17 00:00:00 2001 From: Thu Pham Date: Wed, 27 Mar 2024 17:11:51 -0700 Subject: [PATCH 10/14] Updated to be DateControl because this is what it really is --- src/controls/DateControl.test.tsx | 83 +++++++++++++++++++ .../{DatetimeControl.tsx => DateControl.tsx} | 18 ++-- src/controls/DatetimeControl.test.tsx | 55 ------------ src/renderer-registry-entries.ts | 8 +- ...ol.stories.tsx => DateControl.stories.tsx} | 47 ++++++++--- .../{datetimeSchema.ts => dateSchema.ts} | 14 ++-- src/ui-schema.ts | 4 + test-setup.ts | 7 +- 8 files changed, 149 insertions(+), 87 deletions(-) create mode 100644 src/controls/DateControl.test.tsx rename src/controls/{DatetimeControl.tsx => DateControl.tsx} (59%) delete mode 100644 src/controls/DatetimeControl.test.tsx rename src/stories/controls/{DatetimeControl.stories.tsx => DateControl.stories.tsx} (52%) rename src/testSchemas/{datetimeSchema.ts => dateSchema.ts} (70%) diff --git a/src/controls/DateControl.test.tsx b/src/controls/DateControl.test.tsx new file mode 100644 index 0000000..560530b --- /dev/null +++ b/src/controls/DateControl.test.tsx @@ -0,0 +1,83 @@ +import { describe, expect, test, it } from "vitest" +import { render } from "../common/test-render" + +import { screen } from "@testing-library/react" +import { + dateSchema, + dateUISchema, + dateUISchemaWithRule, +} from "../testSchemas/dateSchema" +import { isDateControl, rankWith } from "@jsonforms/core" +import { UISchema } from ".." + +describe("DateControlTester", () => { + test("tester works", () => { + const uiSchema = { + type: "Control", + scope: "#/properties/date", + } + const schema = { + type: "string", + title: "The Future is Now", + format: "date", + } + const context = { rootSchema: dateSchema, config: {} } + + expect(rankWith(1, isDateControl)(uiSchema, schema, context)).toBe(1) + }) +}) +describe("DateControl", () => { + // FYI this date is treated as UTC + const timestamp: Date = new Date("2023-07-18") + const title = "The Future is Now" + test("renders a datetime input with no UISchema provided", async () => { + render({ + schema: dateSchema, + }) + await screen.findByText(title) + }) + + it("Follows the hide rule", () => { + render({ + data: { date: timestamp }, + schema: dateSchema, + uischema: dateUISchemaWithRule, + }) + expect(screen.queryByText(title)).toBeNull() + }) + + it("renders when data is included", async () => { + render({ + data: { date: timestamp }, + schema: dateSchema, + uischema: dateUISchema, + }) + await screen.findByText(title) + // but date is localized to the local timezone (EST for our tests) + // which is why it's 2023-07-17 + // Should use the default date format + await screen.findByDisplayValue("07/17/2023") + }) + + it("respects dateFormat", async () => { + render({ + data: { date: timestamp }, + schema: dateSchema, + uischema: { + type: "VerticalLayout", + elements: [ + { + type: "Control", + scope: "#/properties/date", + options: { + dateFormat: "YYYY MM DD", + }, + }, + ], + } satisfies UISchema, + }) + // but date is localized to the local timezone (EST for our tests) + // which is why it's 2023-07-17 + await screen.findByDisplayValue("2023 07 17") + }) +}) diff --git a/src/controls/DatetimeControl.tsx b/src/controls/DateControl.tsx similarity index 59% rename from src/controls/DatetimeControl.tsx rename to src/controls/DateControl.tsx index ab249c4..e0c63e2 100644 --- a/src/controls/DatetimeControl.tsx +++ b/src/controls/DateControl.tsx @@ -2,8 +2,9 @@ import { ControlProps } from "@jsonforms/core" import { withJsonFormsControlProps } from "@jsonforms/react" import { DatePicker, Form } from "antd" import dateFnsGenerateConfig from "rc-picker/lib/generate/dateFns" +import { DateControlOptions } from ".." -interface DatetimeControlProps extends ControlProps { +interface DateControlProps extends ControlProps { data: string handleChange(path: string, value: Date | null): void path: string @@ -11,7 +12,7 @@ interface DatetimeControlProps extends ControlProps { const MyDatePicker = DatePicker.generatePicker(dateFnsGenerateConfig) -export function DatetimeControl({ +export function DateControl({ data, handleChange, path, @@ -19,17 +20,20 @@ export function DatetimeControl({ visible, id, required, -}: DatetimeControlProps) { - const dateFormat = "MM/DD/YYYY" + uischema, +}: DateControlProps) { + const options: DateControlOptions = + (uischema.options as DateControlOptions) ?? {} + const format = options.dateFormat ?? "MM/DD/YYYY" return !visible ? null : ( handleChange(path, e)} /> ) } -export const DatetimeRenderer = withJsonFormsControlProps(DatetimeControl) +export const DateRenderer = withJsonFormsControlProps(DateControl) diff --git a/src/controls/DatetimeControl.test.tsx b/src/controls/DatetimeControl.test.tsx deleted file mode 100644 index 4984c5e..0000000 --- a/src/controls/DatetimeControl.test.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { describe, expect, test, it } from "vitest" -import { render } from "../common/test-render" - -import { screen } from "@testing-library/react" -import { - datetimeSchema, - datetimeUISchema, - datetimeUISchemaWithRule, -} from "../testSchemas/datetimeSchema" -import { isDateTimeControl, rankWith } from "@jsonforms/core" - -describe("DatetimeControlTester", () => { - test("tester works", () => { - const uiSchema = { - type: "Control", - scope: "#/properties/datetime", - } - const schema = { - type: "string", - title: "The Future is Now", - format: "date-time", - } - const context = { rootSchema: datetimeSchema, config: {} } - - expect(rankWith(1, isDateTimeControl)(uiSchema, schema, context)).toBe(1) - }) -}) -describe("DatetimeControl", () => { - const timestamp = "2023-07-18T01:02:01.182Z" - const title = "The Future is Now" - test("renders a datetime input with no UISchema provided", async () => { - render({ - schema: datetimeSchema, - }) - await screen.findByText(title) - }) - - it("Follows the hide rule", () => { - render({ - data: { datetime: timestamp }, - schema: datetimeSchema, - uischema: datetimeUISchemaWithRule, - }) - expect(screen.queryByText(title)).toBeNull() - }) - - it("renders when data is included", async () => { - render({ - data: { datetime: timestamp }, - schema: datetimeSchema, - uischema: datetimeUISchema, - }) - await screen.findByText(title) - }) -}) diff --git a/src/renderer-registry-entries.ts b/src/renderer-registry-entries.ts index 7621c8e..10ac4fb 100644 --- a/src/renderer-registry-entries.ts +++ b/src/renderer-registry-entries.ts @@ -19,7 +19,7 @@ import { or, isPrimitiveArrayControl, isOneOfControl, - isDateTimeControl, + isDateControl, isAnyOfControl, } from "@jsonforms/core" import { withJsonFormsCellProps } from "@jsonforms/react" @@ -40,7 +40,7 @@ import { ObjectArrayRenderer, PrimitiveArrayRenderer, } from "./controls/ArrayControl" -import { DatetimeRenderer } from "./controls/DatetimeControl" +import { DateRenderer } from "./controls/DateControl" // Ordered from lowest rank to highest rank. Higher rank renderers will be preferred over lower rank renderers. @@ -78,8 +78,8 @@ export const rendererRegistryEntries: JsonFormsRendererRegistryEntry[] = [ renderer: NumericRenderer, }, { - tester: rankWith(3, isDateTimeControl), - renderer: DatetimeRenderer, + tester: rankWith(3, isDateControl), + renderer: DateRenderer, }, { tester: rankWith( diff --git a/src/stories/controls/DatetimeControl.stories.tsx b/src/stories/controls/DateControl.stories.tsx similarity index 52% rename from src/stories/controls/DatetimeControl.stories.tsx rename to src/stories/controls/DateControl.stories.tsx index 16a23c3..21c4023 100644 --- a/src/stories/controls/DatetimeControl.stories.tsx +++ b/src/stories/controls/DateControl.stories.tsx @@ -1,17 +1,15 @@ import { Meta, StoryObj } from "@storybook/react" import { rendererRegistryEntries } from "../../renderer-registry-entries" import { StorybookAntDJsonForm } from "../../common/StorybookAntDJsonForm" -import { - datetimeSchema, - datetimeUISchema, -} from "../../testSchemas/datetimeSchema" +import { dateSchema, dateUISchema } from "../../testSchemas/dateSchema" +import { UISchema } from "../.." const meta: Meta = { - title: "Control/Datetime", + title: "Control/Date", component: StorybookAntDJsonForm, tags: ["autodocs"], args: { - jsonSchema: datetimeSchema, + jsonSchema: dateSchema, rendererRegistryEntries: [...rendererRegistryEntries], }, argTypes: { @@ -29,21 +27,44 @@ const meta: Meta = { export default meta type Story = StoryObj -export const Datetime: Story = { +export const RegularDate: Story = { tags: ["autodocs"], args: { - jsonSchema: datetimeSchema, - uiSchema: datetimeUISchema, + jsonSchema: dateSchema, + uiSchema: dateUISchema, }, } -export const RequiredDatetime: Story = { +export const RequiredDate: Story = { tags: ["autodocs"], args: { jsonSchema: { - ...datetimeSchema, - required: ["datetime"], + ...dateSchema, + required: ["date"], }, - uiSchema: datetimeUISchema, + uiSchema: dateUISchema, + }, +} + +export const DateWithOptionFormat: Story = { + tags: ["autodocs"], + args: { + data: { date: new Date("2021-01-01") }, + jsonSchema: { + ...dateSchema, + required: ["date"], + }, + uiSchema: { + type: "VerticalLayout", + elements: [ + { + type: "Control", + scope: "#/properties/date", + options: { + dateFormat: "YYYY MM DD", + }, + }, + ], + } satisfies UISchema, }, } diff --git a/src/testSchemas/datetimeSchema.ts b/src/testSchemas/dateSchema.ts similarity index 70% rename from src/testSchemas/datetimeSchema.ts rename to src/testSchemas/dateSchema.ts index e475c7e..36730b9 100644 --- a/src/testSchemas/datetimeSchema.ts +++ b/src/testSchemas/dateSchema.ts @@ -2,33 +2,33 @@ import { JSONSchema } from "json-schema-to-ts" import { UISchema } from "../ui-schema" import { RuleEffect } from "@jsonforms/core" -export const datetimeSchema = { +export const dateSchema = { type: "object", properties: { - datetime: { + date: { type: "string", title: "The Future is Now", - format: "date-time", + format: "date", }, }, } satisfies JSONSchema -export const datetimeUISchema = { +export const dateUISchema = { type: "VerticalLayout", elements: [ { type: "Control", - scope: "#/properties/datetime", + scope: "#/properties/date", }, ], } satisfies UISchema -export const datetimeUISchemaWithRule = { +export const dateUISchemaWithRule = { type: "VerticalLayout", elements: [ { type: "Control", - scope: "#/properties/datetime", + scope: "#/properties/date", rule: { effect: RuleEffect.HIDE, condition: {}, diff --git a/src/ui-schema.ts b/src/ui-schema.ts index 3393013..919eadd 100644 --- a/src/ui-schema.ts +++ b/src/ui-schema.ts @@ -332,3 +332,7 @@ export type NumericControlOptions = { addonBefore?: InputNumberProps["addonBefore"] addonAfter?: InputNumberProps["addonAfter"] } + +export type DateControlOptions = { + dateFormat?: string +} diff --git a/test-setup.ts b/test-setup.ts index 3faeaf6..d511fec 100644 --- a/test-setup.ts +++ b/test-setup.ts @@ -1,12 +1,17 @@ // context: https://github.com/testing-library/jest-dom/pull/511 import "@testing-library/jest-dom/vitest" import { cleanup } from "@testing-library/react" -import { afterEach } from "vitest" +import { afterEach, beforeAll } from "vitest" // TODO: figure out if this is still necessary: // @ts-expect-error ignore -- this solves issue where RTL throws this error "this environment not configured for act" global.IS_REACT_ACT_ENVIRONMENT = true +beforeAll(() => { + // set timezone to US/Eastern for tests + process.env.TZ = 'US/Eastern' +}) + global.matchMedia = global.matchMedia || function () { From 6cea6d82e918b47365d775d9ac6735c2abafd667 Mon Sep 17 00:00:00 2001 From: Thu Pham Date: Thu, 28 Mar 2024 09:04:14 -0700 Subject: [PATCH 11/14] Format --- package.json | 8 ++++++-- src/renderer-registry-entries.ts | 1 - test-setup.ts | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 06021f4..bb6c893 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,9 @@ "name": "@great-expectations/jsonforms-antd-renderers", "private": false, "version": "0.0.0-semantic-release", - "files": ["lib/**/*"], + "files": [ + "lib/**/*" + ], "main": "./lib/cjs/index.js", "types": "./lib/cjs/index.d.ts", "exports": { @@ -21,7 +23,9 @@ "access": "public" }, "release": { - "branches": ["main"] + "branches": [ + "main" + ] }, "repository": { "type": "git", diff --git a/src/renderer-registry-entries.ts b/src/renderer-registry-entries.ts index 10ac4fb..8f8786f 100644 --- a/src/renderer-registry-entries.ts +++ b/src/renderer-registry-entries.ts @@ -42,7 +42,6 @@ import { } from "./controls/ArrayControl" import { DateRenderer } from "./controls/DateControl" - // Ordered from lowest rank to highest rank. Higher rank renderers will be preferred over lower rank renderers. export const rendererRegistryEntries: JsonFormsRendererRegistryEntry[] = [ { diff --git a/test-setup.ts b/test-setup.ts index d511fec..34db394 100644 --- a/test-setup.ts +++ b/test-setup.ts @@ -9,7 +9,7 @@ global.IS_REACT_ACT_ENVIRONMENT = true beforeAll(() => { // set timezone to US/Eastern for tests - process.env.TZ = 'US/Eastern' + process.env.TZ = "US/Eastern" }) global.matchMedia = From 5c90b0bce8e6ddd5046b140756215a222cbebcba Mon Sep 17 00:00:00 2001 From: Thu Pham Date: Tue, 9 Apr 2024 18:17:30 -0700 Subject: [PATCH 12/14] Fix setting up timezone for tests --- src/controls/DateControl.test.tsx | 9 +++------ test-global.ts | 3 +++ test-setup.ts | 7 +------ vite.config.ts | 1 + 4 files changed, 8 insertions(+), 12 deletions(-) create mode 100644 test-global.ts diff --git a/src/controls/DateControl.test.tsx b/src/controls/DateControl.test.tsx index 560530b..60f9b8a 100644 --- a/src/controls/DateControl.test.tsx +++ b/src/controls/DateControl.test.tsx @@ -53,10 +53,8 @@ describe("DateControl", () => { uischema: dateUISchema, }) await screen.findByText(title) - // but date is localized to the local timezone (EST for our tests) - // which is why it's 2023-07-17 // Should use the default date format - await screen.findByDisplayValue("07/17/2023") + await screen.findByDisplayValue("07/18/2023") }) it("respects dateFormat", async () => { @@ -76,8 +74,7 @@ describe("DateControl", () => { ], } satisfies UISchema, }) - // but date is localized to the local timezone (EST for our tests) - // which is why it's 2023-07-17 - await screen.findByDisplayValue("2023 07 17") + + await screen.findByDisplayValue("2023 07 18") }) }) diff --git a/test-global.ts b/test-global.ts new file mode 100644 index 0000000..49069f2 --- /dev/null +++ b/test-global.ts @@ -0,0 +1,3 @@ +export const setup = () => { + process.env.TZ = 'UTC' +} diff --git a/test-setup.ts b/test-setup.ts index 34db394..3faeaf6 100644 --- a/test-setup.ts +++ b/test-setup.ts @@ -1,17 +1,12 @@ // context: https://github.com/testing-library/jest-dom/pull/511 import "@testing-library/jest-dom/vitest" import { cleanup } from "@testing-library/react" -import { afterEach, beforeAll } from "vitest" +import { afterEach } from "vitest" // TODO: figure out if this is still necessary: // @ts-expect-error ignore -- this solves issue where RTL throws this error "this environment not configured for act" global.IS_REACT_ACT_ENVIRONMENT = true -beforeAll(() => { - // set timezone to US/Eastern for tests - process.env.TZ = "US/Eastern" -}) - global.matchMedia = global.matchMedia || function () { diff --git a/vite.config.ts b/vite.config.ts index 9f10272..a1d52d2 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -8,6 +8,7 @@ export default defineConfig({ test: { environment: "jsdom", setupFiles: ["test-setup.ts"], + globalSetup: "test-global.ts", // globals: true // very happy about being able to turn globals off here! }, }) From 2a4c941dc63e3e6b24264234f454a84d4b000bec Mon Sep 17 00:00:00 2001 From: Thu Pham Date: Tue, 9 Apr 2024 18:32:31 -0700 Subject: [PATCH 13/14] Fix type checking for DateControl UISchema --- src/common/schema-derived-types.ts | 3 ++- src/controls/DateControl.test.tsx | 14 ++------------ src/testSchemas/dateSchema.ts | 19 ++++++++++++++++--- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/common/schema-derived-types.ts b/src/common/schema-derived-types.ts index 0916bc9..da6a234 100644 --- a/src/common/schema-derived-types.ts +++ b/src/common/schema-derived-types.ts @@ -5,6 +5,7 @@ import { NumericControlOptions, OneOfControlOptions, TextControlOptions, + DateControlOptions, UISchema, } from ".." @@ -22,7 +23,7 @@ type JsonSchemaTypeToControlOptions< ? U extends "object" // ObjectControlOptions goes here ? unknown : U extends "string" - ? TextControlOptions + ? TextControlOptions | DateControlOptions : U extends "number" | "integer" ? NumericControlOptions : U extends "array" diff --git a/src/controls/DateControl.test.tsx b/src/controls/DateControl.test.tsx index 60f9b8a..8c9eeb1 100644 --- a/src/controls/DateControl.test.tsx +++ b/src/controls/DateControl.test.tsx @@ -6,6 +6,7 @@ import { dateSchema, dateUISchema, dateUISchemaWithRule, + dateUISchemaWithFormatOption, } from "../testSchemas/dateSchema" import { isDateControl, rankWith } from "@jsonforms/core" import { UISchema } from ".." @@ -61,18 +62,7 @@ describe("DateControl", () => { render({ data: { date: timestamp }, schema: dateSchema, - uischema: { - type: "VerticalLayout", - elements: [ - { - type: "Control", - scope: "#/properties/date", - options: { - dateFormat: "YYYY MM DD", - }, - }, - ], - } satisfies UISchema, + uischema: dateUISchemaWithFormatOption, }) await screen.findByDisplayValue("2023 07 18") diff --git a/src/testSchemas/dateSchema.ts b/src/testSchemas/dateSchema.ts index 36730b9..7008c16 100644 --- a/src/testSchemas/dateSchema.ts +++ b/src/testSchemas/dateSchema.ts @@ -8,7 +8,7 @@ export const dateSchema = { date: { type: "string", title: "The Future is Now", - format: "date", + format: "date" }, }, } satisfies JSONSchema @@ -21,7 +21,20 @@ export const dateUISchema = { scope: "#/properties/date", }, ], -} satisfies UISchema +} satisfies UISchema + +export const dateUISchemaWithFormatOption = { + type: "VerticalLayout", + elements: [ + { + type: "Control", + scope: "#/properties/date", + options: { + dateFormat: "YYYY MM DD", + }, + }, + ], +} satisfies UISchema export const dateUISchemaWithRule = { type: "VerticalLayout", @@ -35,4 +48,4 @@ export const dateUISchemaWithRule = { }, }, ], -} satisfies UISchema +} satisfies UISchema From be3d60d25b9bbf2a59c84f9b7dd71edbea20131b Mon Sep 17 00:00:00 2001 From: Thu Pham Date: Tue, 9 Apr 2024 18:36:35 -0700 Subject: [PATCH 14/14] Lint and format --- src/controls/DateControl.test.tsx | 1 - src/stories/controls/DateControl.stories.tsx | 20 ++++++-------------- src/testSchemas/dateSchema.ts | 2 +- test-global.ts | 2 +- tsconfig.json | 2 +- 5 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/controls/DateControl.test.tsx b/src/controls/DateControl.test.tsx index 8c9eeb1..476c68f 100644 --- a/src/controls/DateControl.test.tsx +++ b/src/controls/DateControl.test.tsx @@ -9,7 +9,6 @@ import { dateUISchemaWithFormatOption, } from "../testSchemas/dateSchema" import { isDateControl, rankWith } from "@jsonforms/core" -import { UISchema } from ".." describe("DateControlTester", () => { test("tester works", () => { diff --git a/src/stories/controls/DateControl.stories.tsx b/src/stories/controls/DateControl.stories.tsx index 21c4023..5d08a4f 100644 --- a/src/stories/controls/DateControl.stories.tsx +++ b/src/stories/controls/DateControl.stories.tsx @@ -1,8 +1,11 @@ import { Meta, StoryObj } from "@storybook/react" import { rendererRegistryEntries } from "../../renderer-registry-entries" import { StorybookAntDJsonForm } from "../../common/StorybookAntDJsonForm" -import { dateSchema, dateUISchema } from "../../testSchemas/dateSchema" -import { UISchema } from "../.." +import { + dateSchema, + dateUISchema, + dateUISchemaWithFormatOption, +} from "../../testSchemas/dateSchema" const meta: Meta = { title: "Control/Date", @@ -54,17 +57,6 @@ export const DateWithOptionFormat: Story = { ...dateSchema, required: ["date"], }, - uiSchema: { - type: "VerticalLayout", - elements: [ - { - type: "Control", - scope: "#/properties/date", - options: { - dateFormat: "YYYY MM DD", - }, - }, - ], - } satisfies UISchema, + uiSchema: dateUISchemaWithFormatOption, }, } diff --git a/src/testSchemas/dateSchema.ts b/src/testSchemas/dateSchema.ts index 7008c16..9fc7a1d 100644 --- a/src/testSchemas/dateSchema.ts +++ b/src/testSchemas/dateSchema.ts @@ -8,7 +8,7 @@ export const dateSchema = { date: { type: "string", title: "The Future is Now", - format: "date" + format: "date", }, }, } satisfies JSONSchema diff --git a/test-global.ts b/test-global.ts index 49069f2..a10760b 100644 --- a/test-global.ts +++ b/test-global.ts @@ -1,3 +1,3 @@ export const setup = () => { - process.env.TZ = 'UTC' + process.env.TZ = "UTC" } diff --git a/tsconfig.json b/tsconfig.json index feea382..5edacc8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,5 +23,5 @@ // TODO: move this to a tsconfig.test.json file so that we only load these types for compiling tests "types": ["@testing-library/jest-dom"] }, - "include": ["src", "test-setup.ts"] + "include": ["src", "test-setup.ts", "test-global.ts"] }