Skip to content

Commit

Permalink
Merge pull request #1198 from Chia-Network/refactor/my-organization
Browse files Browse the repository at this point in the history
Refactor/my organization
  • Loading branch information
wwills2 authored Apr 11, 2024
2 parents 47cdc25 + c479a0f commit c368026
Show file tree
Hide file tree
Showing 31 changed files with 811 additions and 127 deletions.
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"flowbite-typography": "^1.0.3",
"formik": "^2.4.5",
"lodash": "^4.17.21",
"qrcode.react": "^3.1.0",
"react": "^18.2.0",
"react-content-loader": "^7.0.0",
"react-dom": "^18.2.0",
Expand Down
9 changes: 8 additions & 1 deletion src/renderer/api/cadt/v1/governance/governance.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,14 @@ const governanceApi = cadtApi.injectEndpoints({
});
},
}),

getDefaultOrgList: builder.query<{ orgUid: string }[], void>({
query: () => ({
url: `/v1/governance/meta/orgList`,
method: 'GET',
}),
}),
}),
});

export const { useGetGlossaryQuery } = governanceApi;
export const { useGetGlossaryQuery, useGetDefaultOrgListQuery } = governanceApi;
78 changes: 67 additions & 11 deletions src/renderer/api/cadt/v1/organizations/organizations.api.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import {cadtApi, organizationsTag} from "../";
import { cadtApi, organizationsTag } from '../';
// @ts-ignore
import {BaseQueryResult} from "@reduxjs/toolkit/dist/query/baseQueryTypes";
import {Organization} from "@/schemas/Organization.schema";
import { BaseQueryResult } from '@reduxjs/toolkit/dist/query/baseQueryTypes';
import { Organization } from '@/schemas/Organization.schema';

interface GetOrgnaizationsMapResponse {
[index: string]: Organization
[index: string]: Organization;
}

interface CreateOrganizationResponse {
message: string;
orgId: string;
}

const organizationsApi = cadtApi.injectEndpoints({
Expand All @@ -15,9 +20,9 @@ const organizationsApi = cadtApi.injectEndpoints({
method: 'GET',
}),
providesTags: [organizationsTag],
transformResponse(baseQueryReturnValue: BaseQueryResult<Organization[]>): Organization[]{
transformResponse(baseQueryReturnValue: BaseQueryResult<Organization[]>): Organization[] {
return Object.values(baseQueryReturnValue);
}
},
}),

getOrganizationsMap: builder.query<GetOrgnaizationsMapResponse, void | null>({
Expand All @@ -26,12 +31,63 @@ const organizationsApi = cadtApi.injectEndpoints({
method: 'GET',
}),
providesTags: [organizationsTag],
})
})
});
}),

createOrganization: builder.mutation<CreateOrganizationResponse, string>({
query: (orgName: string) => {
const formData: FormData = new FormData();
formData.append('name', orgName);

return {
url: `/v1/organizations/create`,
method: 'POST',
body: formData,
};
},
invalidatesTags: [organizationsTag],
}),

importOrganization: builder.mutation<CreateOrganizationResponse, string>({
query: (orgUid: string) => ({
url: `/v1/organizations`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: { orgUid },
}),
invalidatesTags: [organizationsTag],
}),

deleteOrganization: builder.mutation<any, string>({
query: (orgUid: string) => ({
url: `/v1/organizations`,
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: { orgUid },
}),
invalidatesTags: [organizationsTag],
}),

editOrganization: builder.mutation<any, { orgUid: string; orgName: string }>({
query: ({ orgUid, orgName }) => {
const formData: FormData = new FormData();
formData.append('orgUid', orgUid);
formData.append('name', orgName);

return {
url: `/v1/organizations/edit`,
method: 'PUT',
body: formData,
};
},
}),
}),
});

export const {
useGetOrganizationsListQuery,
useGetOrganizationsMapQuery
} = organizationsApi;
useGetOrganizationsMapQuery,
useCreateOrganizationMutation,
useImportOrganizationMutation,
useDeleteOrganizationMutation,
useEditOrganizationMutation,
} = organizationsApi;
18 changes: 10 additions & 8 deletions src/renderer/components/blocks/buttons/QueryRefetchButton.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import React from "react";
import {Button} from "@/components";
import {FormattedMessage} from "react-intl";
import React from 'react';
import { Button } from '@/components';
import { FormattedMessage } from 'react-intl';

interface QueryRefetchButtonProps {
onRefetch: () => void;
}

const QueryRefetchButton: React.FC<QueryRefetchButtonProps> = ({onRefetch}) => {
const QueryRefetchButton: React.FC<QueryRefetchButtonProps> = ({ onRefetch }) => {
return (
<Button
onClick={() => {onRefetch()}}
onClick={() => {
onRefetch();
}}
>
<FormattedMessage id={"unable-to-load-click-to-retry"} />
<FormattedMessage id="unable-to-load-click-to-retry" />
</Button>
);
}
};

export {QueryRefetchButton};
export { QueryRefetchButton };
5 changes: 2 additions & 3 deletions src/renderer/components/blocks/forms/ConnectForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React, { useCallback } from 'react';
import { noop } from 'lodash';
import { ErrorMessage, Field, Form, Formik } from 'formik';
import * as yup from 'yup';
import { FloatingLabel, HelperText, Spacer, FormButton } from '@/components';
import { FloatingLabel, FormButton, HelperText, Spacer } from '@/components';
import { Alert } from 'flowbite-react';
import { IntlShape, useIntl, FormattedMessage } from 'react-intl';
import { FormattedMessage, IntlShape, useIntl } from 'react-intl';

const validationSchema = yup.object({
apiHost: yup
Expand Down Expand Up @@ -87,7 +87,6 @@ const ConnectForm: React.FC<FormProps> = ({ onSubmit, hasServerError, onClearErr
type="text"
{...field}
onChange={(event) => handleChange(event, field)}
ccccccrjflurktedcrhvrbtgldlgnjicvleikebbgnju
/>
)}
</Field>
Expand Down
54 changes: 54 additions & 0 deletions src/renderer/components/blocks/forms/CreateOrganizationForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, { useCallback } from 'react';
import { ErrorMessage, Field, Form, Formik } from 'formik';
import * as yup from 'yup';
import { Button, FloatingLabel, Spinner } from '@/components';
import { IntlShape, useIntl } from 'react-intl';

const validationSchema = yup.object({
name: yup.string().required('Name is required'),
});

interface FormProps {
onSubmit: (orgName: string) => Promise<any>;
}

const CreateOrganizationForm: React.FC<FormProps> = ({ onSubmit }) => {
const intl: IntlShape = useIntl();

const handleSubmit = useCallback(
async (values: { name: string }, { setSubmitting }) => {
await onSubmit(values.name);
setSubmitting(false);
},
[onSubmit],
); // Include onSuccess in the dependencies array

return (
<Formik initialValues={{ name: '' }} validationSchema={validationSchema} onSubmit={handleSubmit}>
{({ errors, touched, isSubmitting }) => (
<Form>
<div className="mb-4">
<Field name="name">
{({ field }) => (
<FloatingLabel
id="name"
label={intl.formatMessage({ id: 'organization-name' })}
color={errors.name && touched.name && 'error'}
variant="outlined"
type="text"
{...field}
/>
)}
</Field>
{touched.name && <ErrorMessage name="name" component="div" className="text-red-600" />}
</div>
<Button type="submit" disabled={isSubmitting}>
{isSubmitting ? <Spinner size="sm" light={true} /> : 'Submit'}
</Button>
</Form>
)}
</Formik>
);
};

export { CreateOrganizationForm };
87 changes: 87 additions & 0 deletions src/renderer/components/blocks/forms/EditOrganizationForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React, { useCallback } from 'react';
import { ErrorMessage, Field, Form, Formik } from 'formik';
import * as yup from 'yup';
import { Button, FormButton, TextInput } from '@/components';
import { FormattedMessage } from 'react-intl';
import { Organization } from '@/schemas/Organization.schema';

const validationSchema = yup.object({
organizationName: yup.string().required('The organization name must be at least 3 characters').min(3),
});

interface FormProps {
myOrganization: Organization;
onSubmit: (organizationName: string) => Promise<any>;
onCancel: () => void;
}

const EditOrganizationForm: React.FC<FormProps> = ({ myOrganization, onSubmit, onCancel }: FormProps) => {
const handleSubmit = useCallback(
async (values: { organizationName: string }, { setSubmitting }) => {
await onSubmit(values.organizationName);
setSubmitting(false);
},
[onSubmit],
);

const handleChange = useCallback((event, field) => {
field.onChange(event); // Call Formik's original onChange
}, []);

return (
<Formik
initialValues={{ organizationName: myOrganization.name }}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{({ errors, touched, isSubmitting }) => (
<Form>
<div className="mb-4">
<Field name="organizationName">
{({ field }) => (
<div className="flex justify-start align-middle">
<div>
<p className="font-bold text-left text-gray-700 dark:text-gray-400 mr-4">
<FormattedMessage id="name" />
</p>
</div>
<TextInput
className="w-3/5 mb-2"
id="organizationName"
color={errors.organizationName && touched.organizationName && 'failure'}
variant="outlined"
required
type="text"
{...field}
onChange={(event) => handleChange(event, field)}
/>
</div>
)}
</Field>
{touched.organizationName && (
<ErrorMessage name="organizationName" component="div" className="text-red-600" />
)}
<div className="flex justify-start">
<p className="font-bold text-left text-gray-700 dark:text-gray-400 mr-4">
<FormattedMessage id="orguid" />
</p>
<p className="font-normal text-left text-gray-700 dark:text-gray-400 inline-block">
{myOrganization.orgUid}
</p>
</div>
</div>
<div className="space-x-2 flex">
<FormButton isSubmitting={isSubmitting} formikErrors={errors}>
<FormattedMessage id="save" />
</FormButton>
<Button onClick={onCancel} color="gray">
<FormattedMessage id="cancel" />
</Button>
</div>
</Form>
)}
</Formik>
);
};

export { EditOrganizationForm };
56 changes: 56 additions & 0 deletions src/renderer/components/blocks/forms/ImportOrganizationForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, { useCallback } from 'react';
import { ErrorMessage, Field, Form, Formik } from 'formik';
import * as yup from 'yup';
import { Button, FloatingLabel, Spinner } from '@/components';
import { IntlShape, useIntl } from 'react-intl';

const validationSchema = yup.object({
orgUid: yup.string().length(64).required('OrgUid is required'),
});

interface FormProps {
onSubmit: (orgUid: string) => Promise<any>;
}

const ImportOrganizationForm: React.FC<FormProps> = ({ onSubmit }) => {
const intl: IntlShape = useIntl();

const handleSubmit = useCallback(
async (values: { orgUid: string }, { setSubmitting }) => {
await onSubmit(values.orgUid);
setSubmitting(false);
},
[onSubmit],
); // Include onSuccess in the dependencies array

return (
<>
<Formik initialValues={{ orgUid: '' }} validationSchema={validationSchema} onSubmit={handleSubmit}>
{({ errors, touched, isSubmitting }) => (
<Form>
<div className="mb-4">
<Field name="orgUid">
{({ field }) => (
<FloatingLabel
id="name"
label={intl.formatMessage({ id: 'organization-orguid' })}
color={errors.orgUid && touched.orgUid && 'error'}
variant="outlined"
type="text"
{...field}
/>
)}
</Field>
{touched.orgUid && <ErrorMessage name="orgUid" component="div" className="text-red-600" />}
</div>
<Button type="submit" disabled={isSubmitting}>
{isSubmitting ? <Spinner size="sm" light={true} /> : 'Submit'}
</Button>
</Form>
)}
</Formik>
</>
);
};

export { ImportOrganizationForm };
Loading

0 comments on commit c368026

Please sign in to comment.