Implement zod

This commit is contained in:
AriGunawan 2022-10-11 01:38:03 +10:00
parent 5be750a512
commit c246d07c60
8 changed files with 182 additions and 15 deletions

View File

@ -19,7 +19,8 @@
"office-ui-fabric-react": "7.185.7",
"react": "16.13.1",
"react-dom": "16.13.1",
"tslib": "2.3.1"
"tslib": "2.3.1",
"zod": "^3.19.1"
},
"devDependencies": {
"@microsoft/eslint-config-spfx": "1.15.2",

View File

@ -25,6 +25,7 @@ specifiers:
spfx-fast-serve-helpers: ~1.15.0
tslib: 2.3.1
typescript: 4.5.5
zod: ^3.19.1
dependencies:
'@microsoft/sp-core-library': 1.15.2
@ -37,6 +38,7 @@ dependencies:
react: 16.13.1
react-dom: 16.13.1_react@16.13.1
tslib: 2.3.1
zod: 3.19.1
devDependencies:
'@microsoft/eslint-config-spfx': 1.15.2_typescript@4.5.5
@ -15171,3 +15173,7 @@ packages:
validator: 13.7.0
optionalDependencies:
commander: 2.20.3
/zod/3.19.1:
resolution: {integrity: sha512-LYjZsEDhCdYET9ikFu6dVPGp2YH9DegXjdJToSzD9rO6fy4qiRYFoyEYwps88OseJlPyl2NOe2iJuhEhL7IpEA==}
dev: false

View File

@ -2,30 +2,39 @@ import * as React from "react";
import * as ReactDom from "react-dom";
import { Version } from "@microsoft/sp-core-library";
import {
IPropertyPaneConfiguration,
} from "@microsoft/sp-property-pane";
import { IPropertyPaneConfiguration } from "@microsoft/sp-property-pane";
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
import { SPFI, spfi, SPFx } from "@pnp/sp";
import ReactZod from "./components/ReactZod";
import { ErrorMessage } from "./components/ErrorMessage";
import { IReactZodProps, ReactZod } from "./components/ReactZod";
import SharePointHelper from "./utils/SharePointHelper";
export interface IReactZodWebPartProps {
description: string;
}
export default class ReactZodWebPart extends BaseClientSideWebPart<IReactZodWebPartProps> {
private _spfi: SPFI;
private _sp: SPFI;
public render(): void {
const element: React.ReactElement = React.createElement(ReactZod, {});
public async render(): Promise<void> {
let element: React.ReactElement;
try {
const data = await SharePointHelper.GetFormResultsData(this._sp);
element = React.createElement(ReactZod, {
data,
} as IReactZodProps);
} catch (error) {
console.error(error);
element = React.createElement(ErrorMessage);
}
ReactDom.render(element, this.domElement);
}
protected async onInit(): Promise<void> {
await super.onInit();
this._spfi = spfi().using(SPFx(this.context));
this._sp = spfi().using(SPFx(this.context));
}
protected onDispose(): void {

View File

@ -0,0 +1,16 @@
import {
MessageBar,
MessageBarType,
} from "office-ui-fabric-react/lib/MessageBar";
import * as React from "react";
const ErrorMessage = (): JSX.Element => {
return (
<MessageBar messageBarType={MessageBarType.error}>
Failed on getting or parsing data. Please check again your data in the
SharePoint List.
</MessageBar>
);
};
export { ErrorMessage };

View File

@ -1,7 +1,83 @@
import { DetailsList, IColumn } from "office-ui-fabric-react/lib/DetailsList";
import * as React from "react";
import { FormResultsModel } from "../utils/Models";
const ReactZod = () => {
return <section></section>;
interface IReactZodProps {
data: FormResultsModel;
}
const ReactZod = (props: IReactZodProps): JSX.Element => {
const columns: IColumn[] = [
{
key: "Id",
name: "Id",
fieldName: "Id",
minWidth: 10,
maxWidth: 30,
},
{
key: "Title",
name: "Title",
fieldName: "Title",
minWidth: 100,
maxWidth: 150,
},
{
key: "Description",
name: "Description",
fieldName: "Description",
minWidth: 200,
},
{
key: "Qty",
name: "Qty",
fieldName: "Qty",
minWidth: 30,
},
{
key: "Rating",
name: "Rating",
fieldName: "Rating",
minWidth: 50,
maxWidth: 100,
},
{
key: "IsActive",
name: "Is Active",
fieldName: "IsActive",
minWidth: 80,
},
{
key: "Status",
name: "Status",
fieldName: "Status",
minWidth: 50,
},
{
key: "PublishDate",
name: "Publish Date",
fieldName: "PublishDate",
minWidth: 120,
},
{
key: "Contact",
name: "Contact",
fieldName: "Contact",
minWidth: 100,
},
{
key: "Email",
name: "Email",
fieldName: "Email",
minWidth: 150,
},
];
return (
<section>
<DetailsList items={props.data} columns={columns} setKey="set" />
</section>
);
};
export default ReactZod;
export { ReactZod, IReactZodProps };

View File

@ -1,3 +0,0 @@
export default class SharePointHelper {
}

View File

@ -0,0 +1,33 @@
import { z } from "zod";
const dateFormatter = new Intl.DateTimeFormat([], {
year: "numeric",
month: "long",
day: "numeric",
weekday: "short",
});
const FormResultSchema = z.object({
Id: z.number(),
Title: z.string(),
Description: z.string(),
IsActive: z.boolean(),
Qty: z.number().nonnegative(),
Rating: z.number().min(0).max(10),
Email: z.string().email(),
Status: z.enum(["Active", "Done", "Rejected"]),
PublishDate: z
.string()
.transform((value) => (value ? dateFormatter.format(new Date(value)) : "")),
Contact: z
.object({
Title: z.string(),
})
.transform((value) => value.Title),
});
const FormResultsSchema = z.array(FormResultSchema);
type FormResultModel = z.infer<typeof FormResultSchema>;
type FormResultsModel = z.infer<typeof FormResultsSchema>;
export { FormResultsSchema, FormResultModel, FormResultsModel };

View File

@ -0,0 +1,29 @@
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import { SPFI } from "@pnp/sp";
import { FormResultsModel, FormResultsSchema } from "./Models";
export default class SharePointHelper {
public static async GetFormResultsData(sp: SPFI): Promise<FormResultsModel> {
const items = await sp.web.lists
.getByTitle("Form Results")
.items
.expand('Contact')
.select(
"Id",
"Title",
"Description",
"Qty",
"Rating",
"IsActive",
"Status",
"PublishDate",
"Contact/Title",
"Email"
)();
return FormResultsSchema.parse(items);
}
}