Compare commits
12 Commits
40e20d0e64
...
ef43369425
| Author | SHA1 | Date | |
|---|---|---|---|
| ef43369425 | |||
| 37193d2246 | |||
| 87f9119b0b | |||
| f9b6aae927 | |||
| 6683d60be5 | |||
| 3942c54ad9 | |||
| 0a22bc1b8f | |||
| 237f8d5742 | |||
| 8d72172e0a | |||
| 90aa5e06f2 | |||
| 178f27cfe2 | |||
| f4c6cdab3b |
@@ -31,8 +31,7 @@ async def create(schema: ContractCreate, reg=Depends(get_authed_tenant_registry)
|
||||
contract_dict = schema.model_dump()
|
||||
del(contract_dict['draft_id'])
|
||||
|
||||
lawyer = await Entity.get(reg.db, reg.user.entity_id)
|
||||
contract_dict['lawyer'] = lawyer.model_dump()
|
||||
contract_dict['lawyer'] = reg.partner.model_dump()
|
||||
|
||||
contract_dict['name'] = draft.name
|
||||
contract_dict['title'] = draft.title
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import datetime
|
||||
from typing import List
|
||||
|
||||
from beanie import PydanticObjectId
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from firm.contract.models import ContractDraft, DraftProvision, DraftParty, Contract
|
||||
|
||||
from firm.entity.models import Entity
|
||||
from firm.core.schemas import Writer, Reader
|
||||
from firm.core.models import DictionaryEntry
|
||||
from firm.core.models import DictionaryEntry, ForeignKey
|
||||
|
||||
|
||||
class ContractDraftRead(Reader, ContractDraft):
|
||||
@@ -68,7 +69,7 @@ class ContractRead(Reader, Contract):
|
||||
class ContractCreate(Writer):
|
||||
date: datetime.date
|
||||
location: str
|
||||
draft_id: str
|
||||
draft_id: PydanticObjectId = ForeignKey(resource="contracts/drafts", schema="ContractDraft")
|
||||
|
||||
class ContractInit(BaseModel):
|
||||
date: datetime.date
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
from fastapi import HTTPException, Depends
|
||||
|
||||
from hub.auth import get_current_user
|
||||
|
||||
from firm.current_firm import CurrentFirmModel, Partner
|
||||
from firm.db import get_db_client
|
||||
from firm.current_firm import CurrentFirmModel
|
||||
from firm.entity.models import Entity
|
||||
|
||||
|
||||
class Registry:
|
||||
user = None
|
||||
partner = None
|
||||
|
||||
def __init__(self, db_client, instance, firm):
|
||||
self.db = db_client[f"tenant_{instance}_{firm}"]
|
||||
@@ -14,11 +18,14 @@ class Registry:
|
||||
|
||||
self.current_firm = CurrentFirmModel.get_current(self.db)
|
||||
|
||||
def set_user(self, user):
|
||||
async def set_user(self, user):
|
||||
for firm in user.firms:
|
||||
if firm.instance == self.instance and firm.firm == self.firm:
|
||||
partner = await Partner.get_by_user_id(self.db, user.id)
|
||||
partner_entity = await Entity.get(self.db, partner.entity_id)
|
||||
self.user = user
|
||||
self.db.user = user
|
||||
self.partner = partner_entity
|
||||
self.db.partner = partner_entity
|
||||
return
|
||||
|
||||
raise PermissionError
|
||||
@@ -30,9 +37,9 @@ async def get_tenant_registry(instance: str, firm: str, db_client=Depends(get_db
|
||||
|
||||
return registry
|
||||
|
||||
def get_authed_tenant_registry(registry=Depends(get_tenant_registry), user=Depends(get_current_user)) -> Registry:
|
||||
async def get_authed_tenant_registry(registry=Depends(get_tenant_registry), user=Depends(get_current_user)) -> Registry:
|
||||
try:
|
||||
registry.set_user(user)
|
||||
await registry.set_user(user)
|
||||
except PermissionError:
|
||||
raise HTTPException(status_code=404, detail="This firm doesn't exist or you are not allowed to access it.")
|
||||
|
||||
@@ -44,7 +51,7 @@ async def get_uninitialized_registry(instance: str, firm: str, db_client=Depends
|
||||
raise HTTPException(status_code=409, detail="Firm configuration already exists")
|
||||
|
||||
try:
|
||||
registry.set_user(user)
|
||||
await registry.set_user(user)
|
||||
except PermissionError:
|
||||
raise HTTPException(status_code=404, detail="This firm doesn't exist or you are not allowed to access it.")
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class CrudDocument(BaseModel):
|
||||
|
||||
@classmethod
|
||||
async def create(cls, db, create_schema):
|
||||
model_dict = create_schema.model_dump() | {"created_by": db.user.id, "updated_by": db.user.id}
|
||||
model_dict = create_schema.model_dump() | {"created_by": db.partner.id, "updated_by": db.partner.id}
|
||||
document = cls.model_validate(model_dict).model_dump(mode="json")
|
||||
result = await cls._get_collection(db).insert_one(document)
|
||||
|
||||
@@ -52,8 +52,13 @@ class CrudDocument(BaseModel):
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def list(cls, db):
|
||||
return cls._get_collection(db).find({})
|
||||
async def list(cls, db, criteria={}):
|
||||
result = []
|
||||
for document in await cls._get_collection(db).find(criteria).to_list():
|
||||
document["id"] = document.pop("_id")
|
||||
result.append(cls.model_validate(document))
|
||||
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
async def get(cls, db, model_id):
|
||||
@@ -66,7 +71,7 @@ class CrudDocument(BaseModel):
|
||||
|
||||
@classmethod
|
||||
async def update(cls, db, model, update_schema):
|
||||
model_dict = update_schema.model_dump(mode="json") | {"updated_by": db.user.id}
|
||||
model_dict = update_schema.model_dump(mode="json") | {"updated_by": db.partner.id}
|
||||
update_query = {
|
||||
"$set": {field: value for field, value in model_dict.items() if field!= "id" }
|
||||
}
|
||||
|
||||
@@ -36,14 +36,15 @@ class CurrentFirmModel(CrudDocument):
|
||||
class CurrentFirmSchemaRead(Reader):
|
||||
entity: EntityRead
|
||||
partner: EntityRead
|
||||
partner_list: list[EntityRead]
|
||||
instance: str
|
||||
firm: str
|
||||
primary_color: str
|
||||
secondary_color: str
|
||||
|
||||
@classmethod
|
||||
def from_model_and_entities(cls, model, entity, partner):
|
||||
schema = cls(**model.model_dump(mode="json"), entity=entity, partner=partner)
|
||||
def from_model_and_entities(cls, model, entity, partner, partner_list):
|
||||
schema = cls(**model.model_dump(mode="json"), entity=entity, partner=partner, partner_list=partner_list)
|
||||
return schema
|
||||
|
||||
class CurrentFirmSchemaCreate(Writer):
|
||||
|
||||
@@ -10,10 +10,17 @@ current_firm_router = APIRouter()
|
||||
@current_firm_router.get("/", response_model=CurrentFirmSchemaRead, response_description=f"Current Firm records retrieved")
|
||||
async def read(reg=Depends(get_authed_tenant_registry)) -> CurrentFirmSchemaRead:
|
||||
document = await CurrentFirmModel.get_current(reg.db)
|
||||
entity = await Entity.get(reg.db, document.entity_id)
|
||||
firm_entity = await Entity.get(reg.db, document.entity_id)
|
||||
partner = await Partner.get_by_user_id(reg.db, reg.user.id)
|
||||
partner = await Entity.get(reg.db, partner.entity_id)
|
||||
return CurrentFirmSchemaRead.from_model_and_entities(document, EntityRead.from_model(entity), EntityRead.from_model(partner))
|
||||
partner_list = await Partner.list(reg.db)
|
||||
partner_list = await Entity.list(reg.db, {"_id": {"$in": [p.entity_id for p in partner_list]}})
|
||||
return CurrentFirmSchemaRead.from_model_and_entities(
|
||||
document,
|
||||
EntityRead.from_model(firm_entity),
|
||||
EntityRead.from_model(partner),
|
||||
[EntityRead.from_model(p) for p in partner_list]
|
||||
)
|
||||
|
||||
@current_firm_router.post("/", response_description=f"Current Firm added to the database")
|
||||
async def create(schema: CurrentFirmSchemaCreate, reg=Depends(get_uninitialized_registry)) -> CurrentFirmSchemaRead:
|
||||
|
||||
1
gui/rpk-gui/package-lock.json
generated
1
gui/rpk-gui/package-lock.json
generated
@@ -35,6 +35,7 @@
|
||||
"@tiptap/extension-underline": "^2.11.7",
|
||||
"@tiptap/react": "^2.11.7",
|
||||
"@tiptap/starter-kit": "^2.11.7",
|
||||
"dayjs": "^1.11.13",
|
||||
"i18next": "^25.0.1",
|
||||
"i18next-browser-languagedetector": "^8.0.5",
|
||||
"i18next-http-backend": "^3.0.2",
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"@tiptap/extension-underline": "^2.11.7",
|
||||
"@tiptap/react": "^2.11.7",
|
||||
"@tiptap/starter-kit": "^2.11.7",
|
||||
"dayjs": "^1.11.13",
|
||||
"i18next": "^25.0.1",
|
||||
"i18next-browser-languagedetector": "^8.0.5",
|
||||
"i18next-http-backend": "^3.0.2",
|
||||
|
||||
33
gui/rpk-gui/src/components/Cartouche.tsx
Normal file
33
gui/rpk-gui/src/components/Cartouche.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { useTranslation } from "@refinedev/core";
|
||||
import { useContext } from "react";
|
||||
import { FirmContext } from "../contexts/FirmContext";
|
||||
|
||||
type CartoucheProps = {
|
||||
record: any
|
||||
}
|
||||
|
||||
const Cartouche = (props: CartoucheProps) => {
|
||||
const { record } = props;
|
||||
const { translate: t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
<ul>
|
||||
{ record.created_at && <li>{t("resource.created_at")}: {record.created_at} {t("resource.created_at")}: <AuthorField partnerId={record.created_by} /></li> }
|
||||
{ record.updated_at && <li>{t("resource.updated_at")}: {record.updated_at} {t("resource.updated_by")}: <AuthorField partnerId={record.updated_by} /></li> }
|
||||
</ul>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Cartouche;
|
||||
|
||||
const AuthorField = (props: {partnerId: string})=> {
|
||||
const { partnerId } = props;
|
||||
const { partnerMap } = useContext(FirmContext);
|
||||
const { translate: t } = useTranslation();
|
||||
|
||||
if (partnerMap && partnerMap.has(partnerId)) {
|
||||
return <>{ partnerMap.get(partnerId) }</>
|
||||
}
|
||||
return <>{t("REDACTED")}</>
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
import React, { createContext, PropsWithChildren } from 'react';
|
||||
import { IFirm } from "../interfaces";
|
||||
import { useParams } from "react-router";
|
||||
import { useOne } from "@refinedev/core";
|
||||
import { CircularProgress } from "@mui/material";
|
||||
|
||||
type FirmContextType = {
|
||||
currentFirm: IFirm,
|
||||
partnerMap?: Map<string, string>
|
||||
}
|
||||
|
||||
export const FirmContext = createContext<FirmContextType>(
|
||||
@@ -12,13 +15,27 @@ export const FirmContext = createContext<FirmContextType>(
|
||||
|
||||
|
||||
export const FirmContextProvider: React.FC<PropsWithChildren> = ({ children }: PropsWithChildren) => {
|
||||
const { instance, firm } = useParams<IFirm>()
|
||||
const { instance, firm } = useParams<IFirm>();
|
||||
const { data, isError, error, isLoading } = useOne({resource: 'firm', id: `${instance}/${firm}/`, errorNotification: false});
|
||||
|
||||
if (instance === undefined || firm === undefined) {
|
||||
return "Error"
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return <CircularProgress />
|
||||
}
|
||||
|
||||
let value: FirmContextType = {
|
||||
currentFirm: {instance, firm}
|
||||
}
|
||||
if (!isError || error?.statusCode != 405) {
|
||||
value.currentFirm.entity = data?.data.entity;
|
||||
value.partnerMap = new Map(data?.data.partner_list.map((item: any) => [item.id, item.label]));
|
||||
}
|
||||
|
||||
return (
|
||||
<FirmContext.Provider value={{currentFirm: {instance, firm}}} >
|
||||
<FirmContext.Provider value={value} >
|
||||
{ children }
|
||||
</FirmContext.Provider>
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
export type IFirm = {
|
||||
instance: string,
|
||||
firm: string
|
||||
entity?: any
|
||||
}
|
||||
|
||||
type User = {
|
||||
|
||||
@@ -8,32 +8,23 @@ import { BaseForm } from "./base-form";
|
||||
type CrudFormProps = {
|
||||
schemaName: string,
|
||||
uiSchema?: UiSchema,
|
||||
resourceBasePath?: string,
|
||||
resource: string,
|
||||
id?: string,
|
||||
onSuccess?: (data: any) => void,
|
||||
record?: any,
|
||||
resourceBasePath: string,
|
||||
onSubmit: (data: any) => void,
|
||||
defaultValue?: any,
|
||||
children?: ReactNode
|
||||
}
|
||||
|
||||
export const CrudForm: React.FC<CrudFormProps> = (props) => {
|
||||
const { schemaName, uiSchema, resourceBasePath="" ,resource, id, onSuccess, defaultValue, children } = props;
|
||||
|
||||
const { onFinish, query, formLoading } = useForm({
|
||||
resource: resourceBasePath == "" ? resource : `${resourceBasePath}/${resource}`,
|
||||
action: id === undefined ? "create" : "edit",
|
||||
redirect: "show",
|
||||
id,
|
||||
onMutationSuccess: (data: any) => { if (onSuccess) { onSuccess(data) } },
|
||||
});
|
||||
const { schemaName, uiSchema, record, resourceBasePath, defaultValue, children, onSubmit } = props;
|
||||
|
||||
const [schema, setSchema] = useState({});
|
||||
const [schemaLoading, setSchemaLoading] = useState(true);
|
||||
useEffect(() => {
|
||||
const fetchSchema = async () => {
|
||||
try {
|
||||
const resourceSchema = id === undefined ? await jsonschemaProvider.getCreateResourceSchema(schemaName)
|
||||
: await jsonschemaProvider.getCardResourceSchema(schemaName);
|
||||
const resourceSchema = record === undefined ? await jsonschemaProvider.getCreateResourceSchema(schemaName)
|
||||
: await jsonschemaProvider.getUpdateResourceSchema(schemaName);
|
||||
setSchema(resourceSchema);
|
||||
setSchemaLoading(false);
|
||||
} catch (error) {
|
||||
@@ -44,19 +35,18 @@ export const CrudForm: React.FC<CrudFormProps> = (props) => {
|
||||
fetchSchema();
|
||||
}, []);
|
||||
|
||||
if(formLoading || schemaLoading) {
|
||||
if(schemaLoading) {
|
||||
return <CircularProgress />
|
||||
}
|
||||
|
||||
const record = query?.data?.data || defaultValue;
|
||||
return (
|
||||
<BaseForm
|
||||
schema={schema}
|
||||
uiSchema={uiSchema}
|
||||
formData={record}
|
||||
formData={record || defaultValue}
|
||||
resourceBasePath={resourceBasePath}
|
||||
onSubmit={
|
||||
(data: any) => onFinish(data)
|
||||
(data: any) => onSubmit(data)
|
||||
}
|
||||
children={children}
|
||||
/>
|
||||
|
||||
@@ -25,9 +25,11 @@ declare module "@tiptap/core" {
|
||||
export default Extension.create<IndentOptions>({
|
||||
name: "indent",
|
||||
|
||||
defaultOptions: {
|
||||
addOptions() {
|
||||
return {
|
||||
types: ["paragraph", "heading"],
|
||||
margin: 40
|
||||
}
|
||||
},
|
||||
|
||||
addGlobalAttributes() {
|
||||
|
||||
@@ -32,6 +32,21 @@ export const jsonschemaProvider = {
|
||||
return readSchema
|
||||
},
|
||||
|
||||
getReadOnlyResourceSchema: async (resourceName: string): Promise<CrudRJSFSchema> => {
|
||||
const updateSchema = await getResourceSchema(`${resourceName}Update`);
|
||||
const readSchema = await getResourceSchema(`${resourceName}Read`);
|
||||
|
||||
for (let prop_name in readSchema.properties) {
|
||||
if (updateSchema.hasOwnProperty(prop_name)) {
|
||||
delete readSchema.properties[prop_name];
|
||||
} else {
|
||||
readSchema.properties[prop_name].readOnly = true;
|
||||
}
|
||||
}
|
||||
|
||||
return readSchema
|
||||
},
|
||||
|
||||
getUpdateResourceSchema: async (resourceName: string): Promise<CrudRJSFSchema> => {
|
||||
return getResourceSchema(`${resourceName}Update`)
|
||||
},
|
||||
@@ -59,10 +74,12 @@ function convertCamelToSnake(str: string): string {
|
||||
}
|
||||
|
||||
function buildResource(rawSchemas: RJSFSchema, resourceName: string) {
|
||||
let resource;
|
||||
if (rawSchemas.components.schemas[resourceName] === undefined) {
|
||||
throw new Error(`Resource "${resourceName}" not found in schema.`);
|
||||
}
|
||||
|
||||
const shortResourceName = convertCamelToSnake(resourceName.replace(/(-Input|Create|Update)$/g, ""));
|
||||
resource = structuredClone(rawSchemas.components.schemas[resourceName]);
|
||||
let resource = structuredClone(rawSchemas.components.schemas[resourceName]);
|
||||
resource.components = { schemas: {} };
|
||||
for (let prop_name in resource.properties) {
|
||||
let prop = resource.properties[prop_name];
|
||||
@@ -110,13 +127,19 @@ function resolveReference(rawSchemas: RJSFSchema, resource: any, prop_reference:
|
||||
|
||||
function changePropertiesOrder(resource: any) {
|
||||
let created_at;
|
||||
let created_by;
|
||||
let updated_at;
|
||||
let updated_by;
|
||||
let new_properties: any = {};
|
||||
for (let prop_name in resource.properties) {
|
||||
if (prop_name == 'created_at') {
|
||||
created_at = resource.properties[prop_name];
|
||||
} else if (prop_name == 'created_by') {
|
||||
created_by = resource.properties[prop_name];
|
||||
} else if (prop_name == 'updated_at') {
|
||||
updated_at = resource.properties[prop_name];
|
||||
} else if (prop_name == 'updated_by') {
|
||||
updated_by = resource.properties[prop_name];
|
||||
}else {
|
||||
new_properties[prop_name] = resource.properties[prop_name];
|
||||
}
|
||||
@@ -124,9 +147,15 @@ function changePropertiesOrder(resource: any) {
|
||||
if (created_at) {
|
||||
new_properties['created_at'] = created_at;
|
||||
}
|
||||
if (created_by) {
|
||||
new_properties['created_by'] = created_by;
|
||||
}
|
||||
if (updated_at) {
|
||||
new_properties['updated_at'] = updated_at;
|
||||
}
|
||||
if (updated_by) {
|
||||
new_properties['updated_by'] = updated_by;
|
||||
}
|
||||
resource.properties = new_properties
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { Route, Routes } from "react-router";
|
||||
import List from "./base-page/List";
|
||||
import Edit from "./base-page/Edit";
|
||||
import New from "./base-page/New";
|
||||
|
||||
type Contract = {
|
||||
export type Contract = {
|
||||
id: string,
|
||||
label: string
|
||||
}
|
||||
@@ -13,7 +12,6 @@ export const ContractRoutes = () => {
|
||||
<Routes>
|
||||
<Route index element={ <ListContract /> } />
|
||||
<Route path="/edit/:record_id" element={ <EditContract /> } />
|
||||
<Route path="/create" element={ <CreateContract /> } />
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
@@ -28,7 +26,3 @@ const ListContract = () => {
|
||||
const EditContract = () => {
|
||||
return <Edit<Contract> resource={`contracts`} schemaName={"Contract"} />
|
||||
}
|
||||
|
||||
const CreateContract = () => {
|
||||
return <New<Contract> resource={`contracts`} schemaName={"Contract"} />
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Route, Routes } from "react-router";
|
||||
import { Navigate, Route, Routes, useParams } from "react-router";
|
||||
import { CircularProgress } from "@mui/material";
|
||||
import React, { useContext, useState } from "react";
|
||||
import { useOne } from "@refinedev/core";
|
||||
import { useOne, useTranslation } from "@refinedev/core";
|
||||
import { BaseForm } from "../../lib/crud/components/base-form";
|
||||
import { ForeignKeyReference, ForeignKeySchema } from "../../lib/crud/components/widgets/foreign-key";
|
||||
|
||||
@@ -9,6 +9,8 @@ import { FirmContext } from "../../contexts/FirmContext";
|
||||
import List from "./base-page/List";
|
||||
import Edit from "./base-page/Edit";
|
||||
import New from "./base-page/New";
|
||||
import { Contract } from "./ContractRoutes";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
type Draft = {
|
||||
id: string,
|
||||
@@ -33,7 +35,63 @@ const ListDraft = () => {
|
||||
}
|
||||
|
||||
const EditDraft = () => {
|
||||
return <Edit<Draft> resource={`contracts/drafts`} schemaName={"ContractDraft"} />
|
||||
const { currentFirm } = useContext(FirmContext);
|
||||
const { record_id } = useParams();
|
||||
const resourceBasePath = `firm/${currentFirm.instance}/${currentFirm.firm}`
|
||||
|
||||
const { data, isLoading } = useOne({
|
||||
resource: `${resourceBasePath}/contracts/drafts`,
|
||||
id: record_id
|
||||
})
|
||||
|
||||
if (isLoading) {
|
||||
return <CircularProgress />
|
||||
}
|
||||
|
||||
if (!data?.data) {
|
||||
return <Navigate to="../" />
|
||||
}
|
||||
|
||||
const draft = data?.data
|
||||
const readOnly = draft.status === "published";
|
||||
|
||||
const uiSchema = {
|
||||
"ui:readonly": readOnly
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Edit<Draft> resource={"contracts/drafts"} schemaName={"ContractDraft"} uiSchema={uiSchema} />
|
||||
<ContractCreate draft={draft}></ContractCreate>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const ContractCreate = (props: { draft: any}) => {
|
||||
const { translate: t } = useTranslation();
|
||||
const { draft } = props;
|
||||
|
||||
if (draft.status === "published") {
|
||||
return <h4>{t("resource.draft.already_published") }</h4>
|
||||
}
|
||||
if (draft.status === "in_progress") {
|
||||
return (
|
||||
<>
|
||||
<h4>{ t("resource.draft.todo") + ":" }</h4>
|
||||
<ul>{ draft.todo.map((item: any) => <li>{ item }</li>) }</ul>
|
||||
</>
|
||||
)
|
||||
}
|
||||
return <New<Contract>
|
||||
resource={"contracts"}
|
||||
schemaName={"Contract"}
|
||||
defaultValue={{
|
||||
date: dayjs().format("YYYY-MM-DD"),
|
||||
location: "Los Santos, SA",
|
||||
draft_id: draft.id
|
||||
}}
|
||||
uiSchema={{ draft_id: { 'ui:widget': 'hidden' } }}
|
||||
/>
|
||||
}
|
||||
|
||||
type ForeignKeySubSchema = ForeignKeySchema & {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { UiSchema } from "@rjsf/utils";
|
||||
import { useParams } from "react-router";
|
||||
import { useContext } from "react";
|
||||
import { Button } from "@mui/material";
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import { useParams, Navigate } from "react-router";
|
||||
import { Button, CircularProgress } from "@mui/material";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import SaveIcon from '@mui/icons-material/Save';
|
||||
import { useForm, useTranslation } from "@refinedev/core";
|
||||
import { DeleteButton } from "@refinedev/mui";
|
||||
import { FirmContext } from "../../../contexts/FirmContext";
|
||||
import { CrudForm } from "../../../lib/crud/components/crud-form";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import { DeleteButton } from "@refinedev/mui";
|
||||
import Cartouche from "../../../components/Cartouche";
|
||||
|
||||
type EditProps = {
|
||||
resource: string,
|
||||
@@ -18,17 +19,36 @@ type EditProps = {
|
||||
const Edit = <T,>(props: EditProps) => {
|
||||
const { schemaName, resource, uiSchema } = props;
|
||||
const { currentFirm } = useContext(FirmContext);
|
||||
const { translate: t } = useTranslation();
|
||||
const resourceBasePath = `firm/${currentFirm.instance}/${currentFirm.firm}`
|
||||
const { record_id } = useParams();
|
||||
|
||||
const { onFinish, query, formLoading } = useForm({
|
||||
resource: `${resourceBasePath}/${resource}`,
|
||||
action: "edit",
|
||||
redirect: "show",
|
||||
id: record_id,
|
||||
});
|
||||
|
||||
if (formLoading) {
|
||||
return <CircularProgress />
|
||||
}
|
||||
|
||||
if (!query?.data?.data) {
|
||||
return <Navigate to="../" />
|
||||
}
|
||||
|
||||
const record = query.data.data;
|
||||
return (
|
||||
<>
|
||||
<h2>{record.label}</h2>
|
||||
<Cartouche record={record}/>
|
||||
<CrudForm
|
||||
resourceBasePath={resourceBasePath}
|
||||
schemaName={schemaName}
|
||||
uiSchema={uiSchema}
|
||||
resourceBasePath={resourceBasePath}
|
||||
resource={resource}
|
||||
id={record_id}
|
||||
record={record}
|
||||
onSubmit={(data: any) => onFinish(data)}
|
||||
>
|
||||
<Stack
|
||||
direction="row"
|
||||
@@ -37,7 +57,7 @@ const Edit = <T,>(props: EditProps) => {
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}>
|
||||
<Button type='submit' variant="contained" size="large"><SaveIcon />Save</Button>
|
||||
<Button type='submit' variant="contained" size="large"><SaveIcon />{t("buttons.save")}</Button>
|
||||
<DeleteButton variant="contained" size="large" color="error" recordItemId={record_id}/>
|
||||
</Stack>
|
||||
</CrudForm>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { CrudForm } from "../../../lib/crud/components/crud-form";
|
||||
import { UiSchema } from "@rjsf/utils";
|
||||
import { useContext } from "react";
|
||||
import { useForm, useTranslation } from "@refinedev/core";
|
||||
import { CrudForm } from "../../../lib/crud/components/crud-form";
|
||||
import { FirmContext } from "../../../contexts/FirmContext";
|
||||
import SaveIcon from "@mui/icons-material/Save";
|
||||
import { Button } from "@mui/material";
|
||||
|
||||
type NewProps = {
|
||||
resource: string,
|
||||
@@ -13,16 +16,25 @@ type NewProps = {
|
||||
const New = <T,>(props: NewProps) => {
|
||||
const { schemaName, resource, uiSchema, defaultValue } = props;
|
||||
const { currentFirm } = useContext(FirmContext);
|
||||
const { translate: t } = useTranslation();
|
||||
const resourceBasePath = `firm/${currentFirm.instance}/${currentFirm.firm}`
|
||||
|
||||
const { onFinish } = useForm({
|
||||
resource: `${resourceBasePath}/${resource}`,
|
||||
action: "create",
|
||||
redirect: "show",
|
||||
});
|
||||
|
||||
return (
|
||||
<CrudForm
|
||||
schemaName={schemaName}
|
||||
uiSchema={uiSchema}
|
||||
resourceBasePath={resourceBasePath}
|
||||
resource={resource}
|
||||
defaultValue={defaultValue}
|
||||
/>
|
||||
onSubmit={(data: any) => onFinish(data)}
|
||||
>
|
||||
<Button type='submit' variant="contained" size="large"><SaveIcon />{t("buttons.create")}</Button>
|
||||
</CrudForm>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Route, Routes, Link } from "react-router";
|
||||
import React, { useContext } from "react";
|
||||
import { useForm, useOne, useTranslation } from "@refinedev/core";
|
||||
import { FirmContext, FirmContextProvider } from "../../contexts/FirmContext";
|
||||
import { Header } from "../../components";
|
||||
import { useOne } from "@refinedev/core";
|
||||
import { CrudForm } from "../../lib/crud/components/crud-form";
|
||||
import { IFirm } from "../../interfaces";
|
||||
import { EntityRoutes } from "./EntityRoutes";
|
||||
@@ -33,15 +33,7 @@ export const FirmRoutes = () => {
|
||||
|
||||
const FirmHome = () => {
|
||||
const { currentFirm } = useContext(FirmContext);
|
||||
const { data: firm, isError, error, isLoading } = useOne({resource: 'firm', id: `${currentFirm.instance}/${currentFirm.firm}/`, errorNotification: false})
|
||||
|
||||
if (isLoading) {
|
||||
return <h1>Loading...</h1>
|
||||
}
|
||||
|
||||
if (isError && error?.statusCode == 405) {
|
||||
return <FirmInitForm currentFirm={currentFirm} />
|
||||
}
|
||||
const { translate: t } = useTranslation();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -64,16 +56,26 @@ type FirmInitFormPros = {
|
||||
|
||||
const FirmInitForm = (props: FirmInitFormPros) => {
|
||||
const { currentFirm } = props;
|
||||
const { translate: t } = useTranslation();
|
||||
const resourceBasePath = `firm`
|
||||
|
||||
const { onFinish } = useForm({
|
||||
resource: `${resourceBasePath}/${currentFirm.instance}/${currentFirm.firm}`,
|
||||
action: "create",
|
||||
redirect: "show",
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1>Initialization of {`${currentFirm.instance} / ${currentFirm.firm}`}</h1>
|
||||
|
||||
<CrudForm
|
||||
schemaName={"CurrentFirmSchemaCreate"}
|
||||
resource={`firm/${currentFirm.instance}/${currentFirm.firm}/`}
|
||||
schemaName={"CurrentFirmSchema"}
|
||||
resourceBasePath={resourceBasePath}
|
||||
defaultValue={{corporation: {entity_data: {activity: t("firm.default_activity") }}}}
|
||||
uiSchema={{
|
||||
corporation: {entity_data: {employees: {"ui:style": {"display": "none"}}}},
|
||||
}}
|
||||
onSubmit={(data: any) => onFinish(data)}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useInvalidateAuthStore } from "@refinedev/core";
|
||||
import { useForm, useInvalidateAuthStore } from "@refinedev/core";
|
||||
import { CrudForm } from "../../lib/crud/components/crud-form";
|
||||
import { empty_user } from "../../providers/auth-provider";
|
||||
|
||||
@@ -9,11 +9,19 @@ export const CreateFirm = () => {
|
||||
invalidateAuthStore().then();
|
||||
}
|
||||
|
||||
const resourceBasePath = "hub/users";
|
||||
const { onFinish } = useForm({
|
||||
resource: `${resourceBasePath}/firms`,
|
||||
action: "create",
|
||||
redirect: "list",
|
||||
onMutationSuccess: data => refreshUser()
|
||||
});
|
||||
|
||||
return (
|
||||
<CrudForm
|
||||
schemaName={"FirmCreate"}
|
||||
resource={"hub/users/firms/"}
|
||||
onSuccess={() => { refreshUser() }}
|
||||
schemaName={"Firm"}
|
||||
resourceBasePath={resourceBasePath}
|
||||
onSubmit={(data: any) => onFinish(data)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user