Skip to content

Commit

Permalink
feat: add new record dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
garrylachman committed Jul 10, 2023
1 parent 6a699fb commit c57e9ec
Show file tree
Hide file tree
Showing 12 changed files with 237 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/renderer/components/modals/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './confirm-promise-modal';
export * from './confirm-promise-delete-modal';
export * from './confirm-promise-save-modal';
export * from './confirm-promise-filters-modal';
export * from './promise-new-record-modal';
36 changes: 36 additions & 0 deletions src/renderer/components/modals/promise-new-record-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Center, Icon, Spinner, Text } from '@chakra-ui/react';
import { FaQuoteLeft, FaQuoteRight } from 'react-icons/fa';
import { v4 } from 'uuid';
import { FilterBuilder } from 'renderer/containers/filter-builder';

import { PromiseModal } from './promise-modal';
import { ActionButtonType } from '@electrocrud/buttons';
import { ColumnWithMetadataAndTags } from 'renderer/defenitions/record-object';
import { Suspense } from 'react';
import { InlineSpinner } from '../icons';
import { RecordFormBuilder } from 'renderer/containers/record-editor';

export const PromiseNewRecordModal = (
columnViews: ColumnWithMetadataAndTags[]
) => {
return PromiseModal({
keyu: v4(),
instanceId: v4(),
size: '5xl',
getValue: () => {},
actionButtons: [ActionButtonType.SAVE, ActionButtonType.CANCEL],
title: (
<Text display="inline-flex" fontWeight="medium" textTransform="uppercase">
Add New Record Modal
</Text>
),
children: (properties) => (
<Suspense fallback={<InlineSpinner />}>
<RecordFormBuilder
columns={columnViews}
formRef={properties.formCtxRef}
/>
</Suspense>
),
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Box, Icon, InputRightAddon } from '@chakra-ui/react';
import { Field } from '@saas-ui/forms';
import { FC } from 'react';
import { ColumnWithMetadataAndTags } from 'renderer/defenitions/record-object';
import { findType } from 'renderer/defenitions/record-object/data-types';

export type FormInputTypeDateTime = {
column: ColumnWithMetadataAndTags;
};

export const FormInputDateTime: FC<FormInputTypeDateTime> = ({ column }) => {
const type = findType(column.data_type);
return (
<Field
variant="flushed"
type="datetime-local"
name={column.name}
label={`${column.name} (${column.alias || column.name})`}
defaultValue={column.default_value}
isDisabled={column.has_auto_increment}
isRequired={!column.is_nullable}
help={column.comment}
rules={{
required: column.is_nullable ? false : `${column.name} is required.`,
}}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Box, Icon, InputRightAddon } from '@chakra-ui/react';
import { Field } from '@saas-ui/forms';
import { FC } from 'react';
import { ColumnWithMetadataAndTags } from 'renderer/defenitions/record-object';
import { findType } from 'renderer/defenitions/record-object/data-types';

export type FormInputTypeNumber = {
column: ColumnWithMetadataAndTags;
};

export const FormInputNumber: FC<FormInputTypeNumber> = ({ column }) => {
const type = findType(column.data_type);
return (
<Field
variant="flushed"
type="number"
name={column.name}
label={`${column.name} (${column.alias || column.name})`}
defaultValue={column.default_value}
isDisabled={column.has_auto_increment}
isRequired={!column.is_nullable && !column.has_auto_increment}
max={column.max_length || Number.POSITIVE_INFINITY}
help={column.comment}
rules={{
required:
column.is_nullable || column.has_auto_increment
? false
: `${column.name} is required.`,
}}
rightAddon={
<Box flex={1} display="flex" alignItems="center">
<Icon as={type.icon} />
</Box>
}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Box, Icon, InputRightAddon } from '@chakra-ui/react';
import { Field } from '@saas-ui/forms';
import { FC } from 'react';
import { ColumnWithMetadataAndTags } from 'renderer/defenitions/record-object';
import { findType } from 'renderer/defenitions/record-object/data-types';

export type FormInputTypeText = {
column: ColumnWithMetadataAndTags;
};

export const FormInputText: FC<FormInputTypeText> = ({ column }) => {
const type = findType(column.data_type);
return (
<Field
variant="flushed"
type="text"
name={column.name}
label={`${column.name} (${column.alias || column.name})`}
defaultValue={column.default_value}
isDisabled={column.has_auto_increment}
isRequired={!column.is_nullable}
maxLength={column.max_length}
help={column.comment}
rules={{
required: column.is_nullable ? false : `${column.name} is required.`,
}}
rightAddon={
<Box flex={1} display="flex" alignItems="center">
<Icon as={type.icon} />
</Box>
}
/>
);
};
25 changes: 25 additions & 0 deletions src/renderer/containers/record-editor/form-inputs/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ColumnWithMetadataAndTags } from 'renderer/defenitions/record-object';
import { findType } from 'renderer/defenitions/record-object/data-types';
import { FormInputDateTime } from './form-input-datetime';
import { FormInputNumber } from './form-input-number';
import { FormInputText } from './form-input-text';

export * from './form-input-text';

export const InputFormFactory = (column: ColumnWithMetadataAndTags) => {
switch (findType(column.data_type).name) {
case 'string': {
return FormInputText;
break;
}
case 'number': {
return FormInputNumber;
break;
}
case 'datetime': {
return FormInputDateTime;
break;
}
}
return FormInputText;
};
1 change: 1 addition & 0 deletions src/renderer/containers/record-editor/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './record-form-builder';
25 changes: 25 additions & 0 deletions src/renderer/containers/record-editor/record-form-builder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Form, FormLayout } from '@saas-ui/forms';
import { FC } from 'react';
import { ColumnWithMetadataAndTags } from 'renderer/defenitions/record-object';
import { InputFormFactory } from './form-inputs';

export type RecordFormBuilderProperties = {
columns: ColumnWithMetadataAndTags[];
formRef: any;
};
export const RecordFormBuilder: FC<RecordFormBuilderProperties> = ({
columns,
formRef,
}) => {
return (
// @ts-ignore
<Form ref={formRef}>
<FormLayout>
{columns?.map((column: ColumnWithMetadataAndTags) => {
const Component = InputFormFactory(column);
return <Component key={column.name} column={column} />;
})}
</FormLayout>
</Form>
);
};
1 change: 1 addition & 0 deletions src/renderer/ipc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './use-ipc-table-info';
export * from './use-ipc-read-data';
export * from './use-ipc-delete-data';
export * from './use-ipc-update-data';
export * from './use-ipc-insert-data';
6 changes: 6 additions & 0 deletions src/renderer/ipc/use-ipc-insert-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { InsertRequest, InsertResponse } from '@electrocrud/shared';
import { useBaseRequest } from './base-request';

export const useIPCInsertData = (request: InsertRequest) => {
return useBaseRequest<InsertResponse>(request);
};
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ export const DataTableCard: FC<DataTableCardProperties> = ({

return (
<Box p={0} m={0} flex={1} display="flex" flexDirection="column" h="100%">
<CardHeader py={0}>
<CardHeader py={0} px={0}>
<DataTableHeader
setInternalFilter={setInternalFilter}
setSearchValue={setSearchValue}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import {
} from '@chakra-ui/react';
import { EntityState } from '@reduxjs/toolkit';
import memoize from 'proxy-memoize';
import { FC, useContext, useMemo } from 'react';
import { FC, useContext, useMemo, useState } from 'react';
import { MdSearch } from 'react-icons/md';
import { TbFilter, TbFilterOff, TbPlaylistAdd, TbTrash } from 'react-icons/tb';
import { useSelector } from 'react-redux';
import {
ActionsDropdownMenu,
ActionsDropdownMenuItem,
AddButton,
RippleButton,
} from '@electrocrud/buttons';
import { ConfirmPromiseDeleteModal } from 'renderer/components/modals/confirm-promise-delete-modal';
Expand All @@ -26,6 +27,10 @@ import { StrictViewFilterRO } from 'renderer/defenitions/record-object';
import { useAppDispatch } from 'renderer/store/hooks';
import { ViewFiltersReducer } from 'renderer/store/reducers';
import { RootState } from 'renderer/store/store';
import { PromiseNewRecordModal } from 'renderer/components/modals';
import { useIPCInsertData } from 'renderer/ipc';
import { IPCChannelEnum } from '@electrocrud/shared';
import { useUpdateEffect } from 'usehooks-ts';

type DataTableHeaderProperties = {
setInternalFilter: (any: any) => void;
Expand Down Expand Up @@ -115,6 +120,41 @@ export const DataTableHeader: FC<DataTableHeaderProperties> = ({
[thisViewFilters]
);

const [newRecordState, setNewRecordState] = useState();

const newRecordHandler = async () => {
try {
if (viewState?.columns) {
const result = await PromiseNewRecordModal(viewState?.columns);
if (result) {
setNewRecordState(result);
}
}
} catch {
/* empty */
}
};

const { execute: executeInsert, isExecuted: isInsertExecuted } =
useIPCInsertData({
channel: IPCChannelEnum.INSERT_DATA,
body: {
table: viewState?.table as string,
data: newRecordState || {},
},
});

useUpdateEffect(() => {
if (newRecordState) {
executeInsert();
}
}, [newRecordState]);

useUpdateEffect(() => {
// @ts-ignore
setNewRecordState();
}, [isInsertExecuted]);

return (
<VStack pt={3}>
<HStack justifyContent="space-between" width="100%">
Expand Down Expand Up @@ -145,6 +185,7 @@ export const DataTableHeader: FC<DataTableHeaderProperties> = ({
</InputRightElement>
</InputGroup>
<ActionsDropdownMenu menuName="Filters" items={actions} />
<AddButton size="sm" onClick={newRecordHandler} />
</HStack>
</HStack>
</VStack>
Expand Down

0 comments on commit c57e9ec

Please sign in to comment.