Compare commits
No commits in common. "e5443ba3fa8896d5ee22e8f8a8dc7e9e8f8ab6c0" and "2335da52303da3e6ad09b19a7bf5d6d5310da830" have entirely different histories.
e5443ba3fa
...
2335da5230
42
package-lock.json
generated
42
package-lock.json
generated
|
|
@ -42,7 +42,6 @@
|
|||
"react-window": "^1.8.10",
|
||||
"reactstrap": "^9.2.3",
|
||||
"sass": "^1.79.4",
|
||||
"vite-plugin-env-compatible": "^2.0.1",
|
||||
"yup": "^1.4.0",
|
||||
"zustand": "^4.5.5"
|
||||
},
|
||||
|
|
@ -5276,19 +5275,6 @@
|
|||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
|
||||
"integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv-expand": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
|
||||
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA=="
|
||||
},
|
||||
"node_modules/ejs": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||
|
|
@ -14670,15 +14656,6 @@
|
|||
"vite": ">=2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-env-compatible": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-env-compatible/-/vite-plugin-env-compatible-2.0.1.tgz",
|
||||
"integrity": "sha512-DRrOZTg/W44ojVQQfGSMPEgYQGzp5TeIpt9cpaK35hTOC/b2D7Ffl8/RIgK8vQ0mlnDIUgETcA173bnMEkyzdw==",
|
||||
"dependencies": {
|
||||
"dotenv": "8.2.0",
|
||||
"dotenv-expand": "5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/void-elements": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
|
||||
|
|
@ -18890,16 +18867,6 @@
|
|||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"dotenv": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
|
||||
"integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw=="
|
||||
},
|
||||
"dotenv-expand": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
|
||||
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA=="
|
||||
},
|
||||
"ejs": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||
|
|
@ -25358,15 +25325,6 @@
|
|||
"fs-extra": "^10.0.0"
|
||||
}
|
||||
},
|
||||
"vite-plugin-env-compatible": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-env-compatible/-/vite-plugin-env-compatible-2.0.1.tgz",
|
||||
"integrity": "sha512-DRrOZTg/W44ojVQQfGSMPEgYQGzp5TeIpt9cpaK35hTOC/b2D7Ffl8/RIgK8vQ0mlnDIUgETcA173bnMEkyzdw==",
|
||||
"requires": {
|
||||
"dotenv": "8.2.0",
|
||||
"dotenv-expand": "5.1.0"
|
||||
}
|
||||
},
|
||||
"void-elements": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
"react-window": "^1.8.10",
|
||||
"reactstrap": "^9.2.3",
|
||||
"sass": "^1.79.4",
|
||||
"vite-plugin-env-compatible": "^2.0.1",
|
||||
"yup": "^1.4.0",
|
||||
"zustand": "^4.5.5"
|
||||
},
|
||||
|
|
@ -47,12 +46,7 @@
|
|||
"test": "vite jest",
|
||||
"preview": "vite preview",
|
||||
"eject": "react-scripts eject",
|
||||
"format": "prettier --write .",
|
||||
"g:api": "node src/Extensions/FileGenerator/generateApi.js",
|
||||
"g:column": "node src/Extensions/FileGenerator/generateColumn.js",
|
||||
"g:formutil": "node src/Extensions/FileGenerator/generateformUtils.js",
|
||||
"g:page": "node src/Extensions/FileGenerator/generatePage.js",
|
||||
"g:dashboard": "node src/Extensions/FileGenerator/generateDashboard.js "
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
|
|
|
|||
|
|
@ -1,84 +0,0 @@
|
|||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
// File path where the abilities are stored
|
||||
const ABILITIES_FILE = path.join(__dirname, "./src/utils/hasAbilityFn.ts");
|
||||
|
||||
// Function to normalize the input name to UPPER_SNAKE_CASE (e.g., test_moaz => TEST_MOAZ, TestMoaz => TEST_MOAZ)
|
||||
const normalizeToUpperSnakeCase = (input) => {
|
||||
return input
|
||||
.replace(/([a-z])([A-Z])/g, "$1_$2") // camelCase to snake_case
|
||||
.replace(/[_\s]+/g, "_") // normalize multiple underscores or spaces
|
||||
.toUpperCase(); // Convert to uppercase
|
||||
};
|
||||
|
||||
// Function to capitalize the first letter of a word
|
||||
const capitalizeFirstLetter = (word) => word.charAt(0).toUpperCase() + word.slice(1);
|
||||
|
||||
// Take the name dynamically from the terminal
|
||||
const nameInput = process.argv[2];
|
||||
|
||||
if (!nameInput) {
|
||||
console.error("Please provide a name as an argument.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Normalize input name (handle camelCase, snake_case, PascalCase)
|
||||
const normalizedInput = normalizeToUpperSnakeCase(nameInput);
|
||||
|
||||
// Generate ability functions for the given name
|
||||
const generateAbilityFunctions = (name) => {
|
||||
const capitalized = capitalizeFirstLetter(name.toLowerCase());
|
||||
return `
|
||||
export const canAdd${capitalized} = hasAbility(
|
||||
ABILITIES_ENUM.${name},
|
||||
ABILITIES_VALUES_ENUM.STORE,
|
||||
);
|
||||
export const canEdit${capitalized} = hasAbility(
|
||||
ABILITIES_ENUM.${name},
|
||||
ABILITIES_VALUES_ENUM.UPDATE,
|
||||
);
|
||||
export const canDelete${capitalized} = hasAbility(
|
||||
ABILITIES_ENUM.${name},
|
||||
ABILITIES_VALUES_ENUM.DELETE,
|
||||
);
|
||||
export const canShow${capitalized} = hasAbility(
|
||||
ABILITIES_ENUM.${name},
|
||||
ABILITIES_VALUES_ENUM.SHOW,
|
||||
);
|
||||
export const canIndex${capitalized} = hasAbility(
|
||||
ABILITIES_ENUM.${name},
|
||||
ABILITIES_VALUES_ENUM.INDEX,
|
||||
);
|
||||
`.trim();
|
||||
};
|
||||
|
||||
const updateAbilitiesFile = () => {
|
||||
if (!fs.existsSync(ABILITIES_FILE)) {
|
||||
console.error(`Error: File ${ABILITIES_FILE} does not exist.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the existing content of the file
|
||||
const fileContent = fs.readFileSync(ABILITIES_FILE, "utf-8");
|
||||
|
||||
// Check for duplicates
|
||||
const alreadyExists = fileContent.includes(`canAdd${capitalizeFirstLetter(normalizedInput)}`);
|
||||
if (alreadyExists) {
|
||||
console.log(`Abilities for "${normalizedInput}" already exist. No changes made.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate new abilities
|
||||
const newAbilities = generateAbilityFunctions(normalizedInput);
|
||||
|
||||
// Append the new abilities at the end of the file
|
||||
const updatedContent = `${fileContent.trim()}\n\n${newAbilities}\n`;
|
||||
|
||||
// Write the updated content back to the file
|
||||
fs.writeFileSync(ABILITIES_FILE, updatedContent, "utf-8");
|
||||
console.log(`Abilities for "${normalizedInput}" added successfully to hasAbilityFn.ts.`);
|
||||
};
|
||||
|
||||
// Run the update
|
||||
updateAbilitiesFile();
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
const fs = require('fs');
|
||||
|
||||
// Get the file name from the command line arguments
|
||||
const fileName = process.argv[2];
|
||||
|
||||
// Check if a file name is provided
|
||||
if (!fileName) {
|
||||
console.error('Please provide a file name.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
let FileContainer = `
|
||||
|
||||
import React from "react";
|
||||
import { getInitialValues, getValidationSchema } from "./FormUtil";
|
||||
import { ModalEnum } from "../../../enums/Model";
|
||||
import LayoutModel from "../../../Layout/Dashboard/LayoutModel";
|
||||
import { QueryStatusEnum } from "../../../enums/QueryStatus";
|
||||
import ModelForm from "./ModelForm";
|
||||
import { useAdd${capitalizeFirstLetter(fileName)} } from "../../../api/${fileName}";
|
||||
|
||||
const AddModel: React.FC = () => {
|
||||
const { mutate, status } = useAdd${capitalizeFirstLetter(fileName)}();
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
mutate({
|
||||
...values,
|
||||
});
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<LayoutModel
|
||||
status={status as QueryStatusEnum}
|
||||
ModelEnum={ModalEnum.${capitalizeAllWord(fileName)}_ADD}
|
||||
modelTitle="${fileName}"
|
||||
handleSubmit={handleSubmit}
|
||||
getInitialValues={getInitialValues({})}
|
||||
getValidationSchema={getValidationSchema}
|
||||
>
|
||||
<ModelForm />
|
||||
</LayoutModel>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddModel;
|
||||
|
||||
|
||||
`
|
||||
fs.writeFileSync('src/Pages/'+fileName+"/Model"+"/"+"AddModel.tsx",
|
||||
FileContainer
|
||||
);
|
||||
|
||||
console.log(`File "${fileName}" generated successfully.`);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function capitalizeFirstLetter(word) {
|
||||
return (word).charAt(0).toUpperCase() + (word).slice(1);
|
||||
}
|
||||
|
||||
function capitalizeAllWord(word) {
|
||||
return (word).toUpperCase() ;
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
const fs = require('fs');
|
||||
|
||||
const fileName = process.argv[2]
|
||||
|
||||
|
||||
if (!fileName) {
|
||||
console.error('Please provide a file name.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
let FileContainer = `
|
||||
|
||||
import useAddMutation from "./helper/useAddMutation";
|
||||
import useDeleteMutation from "./helper/useDeleteMutation";
|
||||
import useGetQuery from "./helper/useGetQuery";
|
||||
import useUpdateMutation from "./helper/useUpdateMutation";
|
||||
|
||||
const API = {
|
||||
GET: "/${fileName}",
|
||||
ADD: "/${fileName}",
|
||||
DELETE: "/${fileName}",
|
||||
UPDATE: "/${fileName}",
|
||||
};
|
||||
|
||||
const KEY = "${fileName}";
|
||||
|
||||
export const useGetAll${capitalizeFirstLetter(fileName)} = (params?: any, options?: any) =>
|
||||
useGetQuery(KEY, API.GET, params, options);
|
||||
export const useAdd${capitalizeFirstLetter(fileName)} = () => useAddMutation(KEY, API.ADD);
|
||||
export const useUpdate${capitalizeFirstLetter(fileName)} = (params?: any) => useUpdateMutation(KEY, API.UPDATE);
|
||||
export const useDelete${capitalizeFirstLetter(fileName)} = (params?: any) =>
|
||||
useDeleteMutation(KEY, API.DELETE);
|
||||
|
||||
`
|
||||
fs.writeFileSync('src/api/' + fileName + ".ts",
|
||||
FileContainer
|
||||
);
|
||||
|
||||
console.log(`File "${fileName}" generated successfully.`);
|
||||
|
||||
|
||||
function capitalizeFirstLetter(word) {
|
||||
return (word).charAt(0).toUpperCase() + (word).slice(1);
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
const fs = require('fs');
|
||||
|
||||
// Get the file name from the command line arguments
|
||||
const fileName = process.argv[2];
|
||||
|
||||
// Check if a file name is provided
|
||||
if (!fileName) {
|
||||
console.error('Please provide a file name.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
let FileContainer = `
|
||||
|
||||
import { TableColumnsType } from "antd";
|
||||
import useModalHandler from "../../utils/useModalHandler";
|
||||
import { ModalEnum } from "../../enums/Model";
|
||||
import { useObjectToEdit } from "../../zustand/ObjectToEditState";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
canDelete${capitalizeFirstLetter(fileName)},
|
||||
canEdit${capitalizeFirstLetter(fileName)},
|
||||
canShow${capitalizeFirstLetter(fileName)},
|
||||
} from "../../utils/hasAbilityFn";
|
||||
import ActionButtons from "../../Components/Table/ActionButtons";
|
||||
import ColumnsImage from "../../Components/Columns/ColumnsImage";
|
||||
import { ${capitalizeFirstLetter(fileName)} } from "../../types/${capitalizeFirstLetter(fileName)}";
|
||||
import { useFilterStateState } from "../../zustand/Filter";
|
||||
|
||||
export const useColumns = () => {
|
||||
const { handel_open_model } = useModalHandler();
|
||||
|
||||
const { setObjectToEdit } = useObjectToEdit((state) => state);
|
||||
const navigate = useNavigate();
|
||||
const { setFilter } = useFilterStateState();
|
||||
|
||||
const handelShow = (record: ${capitalizeFirstLetter(fileName)}) => {
|
||||
setFilter({});
|
||||
navigate(record?.id);
|
||||
};
|
||||
|
||||
const handelDelete = (data: ${capitalizeFirstLetter(fileName)}) => {
|
||||
setObjectToEdit(data);
|
||||
handel_open_model(ModalEnum?.${capitalizeAllWord(fileName)}_DELETE);
|
||||
};
|
||||
|
||||
const handleEdit = (record: ${capitalizeFirstLetter(fileName)}) => {
|
||||
setObjectToEdit(record);
|
||||
handel_open_model(ModalEnum?.${capitalizeAllWord(fileName)}_EDIT);
|
||||
};
|
||||
const [t] = useTranslation();
|
||||
|
||||
const columns: TableColumnsType<${capitalizeFirstLetter(fileName)}> = [
|
||||
{
|
||||
title: t("columns.id"),
|
||||
dataIndex: "id",
|
||||
key: "id",
|
||||
align: "center",
|
||||
render: (_text, record) => record?.id,
|
||||
},
|
||||
{
|
||||
title: ("columns.name"),
|
||||
dataIndex: "name",
|
||||
key: "name",
|
||||
align: "center",
|
||||
render: (_text, record) => record?.name,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: t("columns.image"),
|
||||
dataIndex: "image",
|
||||
key: "image",
|
||||
align: "center",
|
||||
render: (_text: any, record: ${capitalizeFirstLetter(fileName)}) => {
|
||||
let str = record?.image;
|
||||
|
||||
return <ColumnsImage src={str} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t("columns.procedure"),
|
||||
key: "actions",
|
||||
align: "center",
|
||||
width: "25vw",
|
||||
render: (_text, record, index) => {
|
||||
return (
|
||||
<ActionButtons
|
||||
canDelete={canDelete${capitalizeFirstLetter(fileName)}}
|
||||
canEdit={canEdit${capitalizeFirstLetter(fileName)}}
|
||||
canShow={canShow${capitalizeFirstLetter(fileName)}}
|
||||
index={index}
|
||||
onDelete={() => handelDelete(record)}
|
||||
onEdit={() => handleEdit(record)}
|
||||
onShow={() => handelShow(record)}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return columns;
|
||||
};
|
||||
|
||||
|
||||
`
|
||||
fs.writeFileSync('src/Pages/'+fileName+"/"+"useTableColumns.tsx",
|
||||
FileContainer
|
||||
);
|
||||
|
||||
console.log(`File "${fileName}" generated successfully.`);
|
||||
|
||||
|
||||
|
||||
function capitalizeFirstLetter(word) {
|
||||
return (word).charAt(0).toUpperCase() + (word).slice(1);
|
||||
}
|
||||
|
||||
function capitalizeAllWord(word) {
|
||||
return (word).toUpperCase() ;
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
const { execSync } = require('child_process');
|
||||
|
||||
const fileName = process.argv[2];
|
||||
|
||||
// Define commands
|
||||
const commands = [
|
||||
`node src/Extensions/FileGenerator/generateApi.js ${fileName}`,
|
||||
`node src/Extensions/FileGenerator/generatePage.js ${fileName}`,
|
||||
`node src/Extensions/FileGenerator/generateTable.js ${fileName}`,
|
||||
`node src/Extensions/FileGenerator/generateColumn.js ${fileName}`,
|
||||
`node src/Extensions/FileGenerator/generateIndex.js ${fileName}`,
|
||||
`node src/Extensions/FileGenerator/generateFormUtils.js ${fileName}`,
|
||||
`node src/Extensions/FileGenerator/generateAddModal.js ${fileName}`,
|
||||
`node src/Extensions/FileGenerator/generateEditModal.js ${fileName}`,
|
||||
`node src/Extensions/FileGenerator/generateModelForm.js ${fileName}`,
|
||||
`node src/Extensions/FileGenerator/generateFilterForm.js ${fileName}`,
|
||||
`node src/Extensions/FileGenerator/generateType.js ${fileName}`,
|
||||
`node src/Extensions/FileGenerator/generateParamsEnum.js ${fileName}`,
|
||||
// `node src/Extensions/FileGenerator/generateRoute.js ${fileName}`,
|
||||
// `node src/Extensions/FileGenerator/generateModelEnum.js ${fileName}`,
|
||||
// `node src/Extensions/FileGenerator/generateAbility.js ${fileName}`
|
||||
|
||||
];
|
||||
|
||||
// Execute each command sequentially
|
||||
const runCommands = () => {
|
||||
for (const command of commands) {
|
||||
try {
|
||||
console.log(`Running: ${command}`);
|
||||
execSync(command, { stdio: 'inherit' });
|
||||
console.log(`${command} executed successfully.\n`);
|
||||
} catch (error) {
|
||||
console.error(`Error executing ${command}:`, error);
|
||||
process.exit(1); // Exit if any command fails
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
runCommands();
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
const fs = require('fs');
|
||||
|
||||
// Get the file name from the command line arguments
|
||||
const fileName = process.argv[2];
|
||||
|
||||
// Check if a file name is provided
|
||||
if (!fileName) {
|
||||
console.error('Please provide a file name.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let FileContainer = `
|
||||
|
||||
import React from "react";
|
||||
import { getInitialValues, getValidationSchema } from "./FormUtil";
|
||||
import { ModalEnum } from "../../../enums/Model";
|
||||
import LayoutModel from "../../../Layout/Dashboard/LayoutModel";
|
||||
import ModelForm from "./ModelForm";
|
||||
import { QueryStatusEnum } from "../../../enums/QueryStatus";
|
||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
||||
import { useUpdate${capitalizeFirstLetter(fileName)} } from "../../../api/${fileName}";
|
||||
import { handelImageState } from "../../../utils/DataToSendImageState";
|
||||
|
||||
const EditModel: React.FC = () => {
|
||||
const { mutate, status } = useUpdate${capitalizeFirstLetter(fileName)}();
|
||||
const { objectToEdit } = useObjectToEdit((state) => state);
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
const Data_to_send = { ...values };
|
||||
const handelImage = handelImageState(Data_to_send, "icon");
|
||||
mutate(handelImage);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<LayoutModel
|
||||
status={status as QueryStatusEnum}
|
||||
ModelEnum={ModalEnum.${capitalizeAllWord(fileName)}_EDIT}
|
||||
modelTitle="${fileName}"
|
||||
handleSubmit={handleSubmit}
|
||||
getInitialValues={getInitialValues(objectToEdit)}
|
||||
getValidationSchema={getValidationSchema}
|
||||
isAddModal={false}
|
||||
>
|
||||
<ModelForm />
|
||||
</LayoutModel>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditModel;
|
||||
|
||||
`
|
||||
fs.writeFileSync('src/Pages/'+fileName+"/Model"+"/"+"EditModel.tsx",
|
||||
FileContainer
|
||||
);
|
||||
|
||||
console.log(`File "${fileName}" generated successfully.`);
|
||||
|
||||
|
||||
function capitalizeFirstLetter(word) {
|
||||
return (word).charAt(0).toUpperCase() + (word).slice(1);
|
||||
}
|
||||
|
||||
function capitalizeAllWord(word) {
|
||||
return (word).toUpperCase() ;
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
const fs = require('fs');
|
||||
|
||||
// Get the file name from the command line arguments
|
||||
const fileName = process.argv[2];
|
||||
|
||||
// Check if a file name is provided
|
||||
if (!fileName) {
|
||||
console.error('Please provide a file name.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let FileContainer = `
|
||||
import React from "react";
|
||||
import ValidationField from "../../../Components/ValidationField/ValidationField";
|
||||
import { Col, Row } from "reactstrap";
|
||||
import { useFormikContext } from "formik";
|
||||
|
||||
const FilterForm = () => {
|
||||
const formik = useFormikContext();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Row>
|
||||
<Col>
|
||||
<ValidationField placeholder="name" label="name" name="name" />
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FilterForm;
|
||||
|
||||
`
|
||||
fs.writeFileSync('src/Pages/' + fileName +"/Model"+"/"+"FilterForm.tsx",
|
||||
FileContainer
|
||||
);
|
||||
|
||||
console.log(`File "${fileName}" generated successfully.`);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function capitalizeFirstLetter(word) {
|
||||
return (word).charAt(0).toUpperCase() + (word).slice(1);
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Get the file name from the command line arguments
|
||||
const fileName = process.argv[2];
|
||||
|
||||
// Check if a file name is provided
|
||||
if (!fileName) {
|
||||
console.error('Please provide a file name.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const folderPath = path.join('src/Pages', fileName, 'Model');
|
||||
|
||||
// Ensure the directory exists (creates the folder if missing)
|
||||
fs.mkdirSync(folderPath, { recursive: true });
|
||||
|
||||
|
||||
let FileContainer = `
|
||||
|
||||
import * as Yup from "yup";
|
||||
import { ${capitalizeFirstLetter(fileName)}, ${capitalizeFirstLetter(fileName)}InitialValues } from "../../../types/${capitalizeFirstLetter(fileName)}";
|
||||
|
||||
export const getInitialValues = (
|
||||
objectToEdit: Partial<${capitalizeFirstLetter(fileName)}>,
|
||||
): ${capitalizeFirstLetter(fileName)}InitialValues => {
|
||||
|
||||
return {
|
||||
id: objectToEdit?.id,
|
||||
name: objectToEdit?.name ?? "",
|
||||
};
|
||||
};
|
||||
|
||||
export const getValidationSchema = () => {
|
||||
// validate input
|
||||
return Yup.object().shape({
|
||||
name: Yup.string().required("validation.required"),
|
||||
});
|
||||
};
|
||||
|
||||
`
|
||||
|
||||
fs.writeFileSync(path.join(folderPath, 'FormUtil.ts'), FileContainer);
|
||||
|
||||
|
||||
console.log(`File "${fileName}" generated successfully.`);
|
||||
|
||||
|
||||
function capitalizeFirstLetter(word) {
|
||||
return (word).charAt(0).toUpperCase() + (word).slice(1);
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
const fs = require('fs');
|
||||
|
||||
// Get the file name from the command line arguments
|
||||
const fileName = process.argv[2];
|
||||
|
||||
// Check if a file name is provided
|
||||
if (!fileName) {
|
||||
console.error('Please provide a file name.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const folderPath = 'src/Pages/'+fileName;
|
||||
|
||||
|
||||
if (!fs.existsSync(folderPath)) {
|
||||
fs.mkdirSync(folderPath, { recursive: true });
|
||||
}
|
||||
|
||||
let FileContainer = `
|
||||
import { useColumns } from "./useTableColumns";
|
||||
import Table from "./Table";
|
||||
import AddModalForm from "./Model/AddModel";
|
||||
import EditModalForm from "./Model/EditModel";
|
||||
|
||||
export {
|
||||
Table,
|
||||
useColumns,
|
||||
AddModalForm,
|
||||
EditModalForm,
|
||||
};
|
||||
|
||||
|
||||
`
|
||||
|
||||
fs.writeFileSync('src/Pages/'+fileName+"/"+"index.tsx",
|
||||
FileContainer
|
||||
);
|
||||
|
||||
console.log(`File "${fileName}" generated successfully.`);
|
||||
|
||||
|
||||
function capitalizeFirstLetter(word) {
|
||||
return (word).charAt(0).toUpperCase() + (word).slice(1);
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
// Path to the ModalEnum file
|
||||
const MODEL_ENUM_FILE = "./src/enums/Model.ts";
|
||||
|
||||
// Function to convert input to UPPER_SNAKE_CASE
|
||||
const toUpperSnakeCase = (input) => {
|
||||
return input
|
||||
.replace(/([a-z])([A-Z])/g, "$1_$2") // Convert camelCase to snake_case
|
||||
.replace(/[_\s]+/g, "_") // Normalize underscores or spaces
|
||||
.toUpperCase(); // Convert to uppercase
|
||||
};
|
||||
|
||||
// Take the name dynamically from the terminal
|
||||
const nameInput = process.argv[2];
|
||||
|
||||
if (!nameInput) {
|
||||
console.error("Please provide a name as an argument.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Generate the enum entries for the given name
|
||||
const generateEnumEntries = (name) => {
|
||||
const baseName = toUpperSnakeCase(name);
|
||||
return [
|
||||
` ${baseName}_EDIT = "${baseName.toLowerCase()}.edit",`,
|
||||
` ${baseName}_ADD = "${baseName.toLowerCase()}.add",`,
|
||||
` ${baseName}_DELETE = "${baseName.toLowerCase()}.delete",`
|
||||
].join("\n");
|
||||
};
|
||||
|
||||
// Update the ModalEnum file
|
||||
const updateModelEnumFile = () => {
|
||||
if (!fs.existsSync(MODEL_ENUM_FILE)) {
|
||||
console.error(`Error: File ${MODEL_ENUM_FILE} does not exist.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the existing content of the file
|
||||
const fileContent = fs.readFileSync(MODEL_ENUM_FILE, "utf-8");
|
||||
|
||||
// Generate the new entries for the given name
|
||||
const newEntries = generateEnumEntries(nameInput);
|
||||
|
||||
// Check if any of the new keys already exist in the file
|
||||
const existingKeys = Array.from(
|
||||
fileContent.matchAll(/(\w+)\s*=\s*".+?"/g),
|
||||
(match) => match[1]
|
||||
);
|
||||
const baseName = toUpperSnakeCase(nameInput);
|
||||
|
||||
const duplicateKeys = existingKeys.filter((key) =>
|
||||
[`${baseName}_EDIT`, `${baseName}_ADD`, `${baseName}_DELETE`].includes(key)
|
||||
);
|
||||
|
||||
if (duplicateKeys.length > 0) {
|
||||
console.log(`The keys ${duplicateKeys.join(", ")} already exist. No changes made.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Inject the new entries before the closing brace of the enum
|
||||
const updatedContent = fileContent.replace(
|
||||
/(export enum ModalEnum {\n)/,
|
||||
`$1${newEntries}\n`
|
||||
);
|
||||
|
||||
// Write the updated content back to the file
|
||||
fs.writeFileSync(MODEL_ENUM_FILE, updatedContent, "utf-8");
|
||||
console.log(`Enum entries for "${nameInput}" added successfully to ModalEnum.`);
|
||||
};
|
||||
|
||||
updateModelEnumFile();
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
const fs = require('fs');
|
||||
|
||||
// Get the file name from the command line arguments
|
||||
const fileName = process.argv[2];
|
||||
|
||||
// Check if a file name is provided
|
||||
if (!fileName) {
|
||||
console.error('Please provide a file name.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let FileContainer = `
|
||||
|
||||
import { Col, Row } from "reactstrap";
|
||||
import ValidationField from "../../../Components/ValidationField/ValidationField";
|
||||
|
||||
const ModelForm = () => {
|
||||
return (
|
||||
<Row className="w-100">
|
||||
<Col>
|
||||
<ValidationField name="name" placeholder="name" label="name" />
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModelForm;
|
||||
|
||||
|
||||
|
||||
`
|
||||
fs.writeFileSync('src/Pages/' + fileName +"/Model"+"/"+"ModelForm.tsx",
|
||||
FileContainer
|
||||
);
|
||||
|
||||
console.log(`File "${fileName}" generated successfully.`);
|
||||
|
||||
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
const fs = require('fs');
|
||||
|
||||
// Get the file name from the command line arguments
|
||||
const fileName = process.argv[2];
|
||||
|
||||
// Check if a file name is provided
|
||||
if (!fileName) {
|
||||
console.error('Please provide a file name.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const folderPath = 'src/Pages/'+fileName;
|
||||
|
||||
|
||||
if (!fs.existsSync(folderPath)) {
|
||||
fs.mkdirSync(folderPath, { recursive: true });
|
||||
}
|
||||
|
||||
|
||||
let FileContainer = `
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { lazy, Suspense } from "react";
|
||||
import { Spin } from "antd";
|
||||
import useSetPageTitle from "../../Hooks/useSetPageTitle";
|
||||
import { ModalEnum } from "../../enums/Model";
|
||||
import { useDelete${capitalizeFirstLetter(fileName)} } from "../../api/${fileName}";
|
||||
import PageHeader from "../../Layout/Dashboard/PageHeader";
|
||||
import FilterLayout from "../../Layout/Dashboard/FilterLayout";
|
||||
import FilterForm from "./Model/FilterForm";
|
||||
import { canAdd${capitalizeFirstLetter(fileName)} } from "../../utils/hasAbilityFn";
|
||||
|
||||
const Table = lazy(() => import("./Table"));
|
||||
const AddModalForm = lazy(() => import("./Model/AddModel"));
|
||||
const EditModalForm = lazy(() => import("./Model/EditModel"));
|
||||
const DeleteModalForm = lazy(
|
||||
() => import("../../Layout/Dashboard/DeleteModels"),
|
||||
);
|
||||
|
||||
const TableHeader = () => {
|
||||
const [t] = useTranslation();
|
||||
const deleteMutation = useDelete${capitalizeFirstLetter(fileName)}();
|
||||
|
||||
useSetPageTitle([
|
||||
{ name: t('page_header.home'), path: "/" },
|
||||
{ name: t('page_header.${fileName}'), path: "${fileName}" },
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className="TableWithHeader">
|
||||
<Suspense fallback={<Spin />}>
|
||||
<PageHeader
|
||||
pageTitle="${fileName}"
|
||||
ModelAbility={ModalEnum?.${capitalizeAllWord(fileName)}_ADD}
|
||||
canAdd={canAdd${capitalizeFirstLetter(fileName)}}
|
||||
/>
|
||||
<FilterLayout
|
||||
sub_children={<FilterForm />}
|
||||
filterTitle="table.${fileName}"
|
||||
/>
|
||||
<Table />
|
||||
<AddModalForm />
|
||||
<EditModalForm />
|
||||
<DeleteModalForm
|
||||
deleteMutation={deleteMutation}
|
||||
ModelEnum={ModalEnum?.${capitalizeAllWord(fileName)}_DELETE}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TableHeader;
|
||||
|
||||
`
|
||||
|
||||
fs.writeFileSync('src/Pages/'+fileName+"/"+"Page.tsx",
|
||||
FileContainer
|
||||
);
|
||||
|
||||
console.log(`File "${fileName}" generated successfully.`);
|
||||
|
||||
|
||||
function capitalizeFirstLetter(word) {
|
||||
return (word).charAt(0).toUpperCase() + (word).slice(1);
|
||||
}
|
||||
|
||||
function capitalizeAllWord(word) {
|
||||
return (word).toUpperCase() ;
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Function to capitalize and add "_ID"
|
||||
function capitalizeAllWord(word) {
|
||||
return word.toUpperCase() + "_ID";
|
||||
}
|
||||
|
||||
const fileName = process.argv[2];
|
||||
|
||||
if (!fileName) {
|
||||
console.error('Please provide a file name.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Define the enum entry to add
|
||||
const enumKey = capitalizeAllWord(fileName);
|
||||
const enumValue = `${fileName.toLowerCase()}_id`;
|
||||
const newEntry = ` ${enumKey} = "${enumValue}",\n`;
|
||||
|
||||
// Path to the params.ts file in `src/enums/`
|
||||
const paramsPath = path.join(__dirname, '../../enums/params.ts');
|
||||
|
||||
try {
|
||||
// Read the current contents of params.ts
|
||||
const fileContents = fs.readFileSync(paramsPath, 'utf-8');
|
||||
|
||||
// Insert the new entry before the closing brace of the enum
|
||||
const updatedContents = fileContents.replace(
|
||||
/(export enum ParamsEnum {\n)/,
|
||||
`$1${newEntry}`
|
||||
);
|
||||
|
||||
// Write the updated contents back to params.ts
|
||||
fs.writeFileSync(paramsPath, updatedContents);
|
||||
console.log(`Enum entry "${enumKey}" added successfully to params.ts.`);
|
||||
} catch (error) {
|
||||
console.error(`Error updating params.ts: ${error}`);
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const ROUTES_FILE = "./src/Routes.tsx"; // Path to the file that contains the route definitions
|
||||
const PAGES_FOLDER = "./src/Pages"; // Folder containing the pages
|
||||
|
||||
// Helper to convert a name to PascalCase
|
||||
const toPascalCase = (str) =>
|
||||
str.replace(/(^\w|_\w)/g, (match) => match.replace("_", "").toUpperCase());
|
||||
|
||||
// Helper to convert a name to lowercase snake_case
|
||||
const toSnakeCase = (str) =>
|
||||
str.replace(/[A-Z]/g, (letter, idx) => (idx ? "_" : "") + letter.toLowerCase());
|
||||
|
||||
// Helper to dynamically create imports and route items
|
||||
const generateRoutes = () => {
|
||||
// Scan the pages folder for directories
|
||||
const pageDirs = fs
|
||||
.readdirSync(PAGES_FOLDER, { withFileTypes: true })
|
||||
.filter((dirent) => dirent.isDirectory())
|
||||
.map((dirent) => dirent.name.toLowerCase()); // Normalize to lowercase
|
||||
|
||||
// Use a Set to ensure no duplicates
|
||||
const uniqueDirs = Array.from(new Set(pageDirs));
|
||||
|
||||
const imports = [];
|
||||
const routes = [];
|
||||
|
||||
uniqueDirs.forEach((page) => {
|
||||
const componentName = toPascalCase(page);
|
||||
const importPath = `./Pages/${page}/Page`;
|
||||
const abilityEnum = toSnakeCase(page).toUpperCase();
|
||||
|
||||
// Add to imports
|
||||
imports.push(
|
||||
`const ${componentName} = React.lazy(() => import("${importPath}"));`
|
||||
);
|
||||
|
||||
// Add to routes
|
||||
routes.push(`
|
||||
{
|
||||
header: "page_header.${toSnakeCase(page)}",
|
||||
element: <${componentName} />,
|
||||
icon: <DefaultIcon />, // Replace with actual icon
|
||||
text: "sidebar.${toSnakeCase(page)}",
|
||||
path: \`/\${ABILITIES_ENUM?.${abilityEnum}}\`,
|
||||
abilities: ABILITIES_ENUM?.${abilityEnum},
|
||||
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
|
||||
prevPath: 0,
|
||||
},
|
||||
`);
|
||||
});
|
||||
|
||||
return { imports, routes };
|
||||
};
|
||||
|
||||
const updateRoutesFile = () => {
|
||||
const { imports, routes } = generateRoutes();
|
||||
|
||||
// Remove duplicates from imports and routes
|
||||
const uniqueImports = [...new Set(imports)];
|
||||
const uniqueRoutes = [...new Set(routes)];
|
||||
|
||||
// Read the existing file
|
||||
const fileContent = fs.readFileSync(ROUTES_FILE, "utf-8");
|
||||
|
||||
// Replace the imports section
|
||||
const updatedImports = fileContent.replace(
|
||||
/\/\/ START: DYNAMIC IMPORTS[\s\S]*?\/\/ END: DYNAMIC IMPORTS/,
|
||||
`// START: DYNAMIC IMPORTS\n${uniqueImports.join("\n")}\n// END: DYNAMIC IMPORTS`
|
||||
);
|
||||
|
||||
// Replace the routes section
|
||||
const updatedRoutes = updatedImports.replace(
|
||||
/\/\/ START: DYNAMIC ROUTES[\s\S]*?\/\/ END: DYNAMIC ROUTES/,
|
||||
`// START: DYNAMIC ROUTES\n${uniqueRoutes.join("\n")}\n// END: DYNAMIC ROUTES`
|
||||
);
|
||||
|
||||
// Write the updated content back
|
||||
fs.writeFileSync(ROUTES_FILE, updatedRoutes, "utf-8");
|
||||
};
|
||||
|
||||
updateRoutesFile();
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
const fs = require('fs');
|
||||
|
||||
// Get the file name from the command line arguments
|
||||
const fileName = process.argv[2];
|
||||
|
||||
// Check if a file name is provided
|
||||
if (!fileName) {
|
||||
console.error('Please provide a file name.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const folderPath = 'src/Pages/'+fileName;
|
||||
|
||||
|
||||
if (!fs.existsSync(folderPath)) {
|
||||
fs.mkdirSync(folderPath, { recursive: true });
|
||||
}
|
||||
|
||||
let FileContainer = `
|
||||
|
||||
|
||||
import { useColumns } from "./useTableColumns";
|
||||
import React from "react";
|
||||
import DataTable from "../../Layout/Dashboard/Table/DataTable";
|
||||
import { useGetAll${capitalizeFirstLetter(fileName)} } from "../../api/${fileName}";
|
||||
import { useFilterState } from "../../Components/Utils/Filter/FilterState";
|
||||
import { useFilterStateState } from "../../zustand/Filter";
|
||||
|
||||
const App: React.FC = () => {
|
||||
const { filterState } = useFilterState();
|
||||
const { Filter } = useFilterStateState();
|
||||
const name = Filter?.name;
|
||||
const sort_by = Filter?.sort_by;
|
||||
|
||||
const response = useGetAll${capitalizeFirstLetter(fileName)}({
|
||||
pagination: true,
|
||||
...filterState,
|
||||
name: filterState.name || name,
|
||||
sort_by,
|
||||
});
|
||||
|
||||
return <DataTable response={response} useColumns={useColumns} />;
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
||||
`
|
||||
|
||||
fs.writeFileSync('src/Pages/'+fileName+"/"+"Table.tsx",
|
||||
FileContainer
|
||||
);
|
||||
|
||||
console.log(`File "${fileName}" generated successfully.`);
|
||||
|
||||
|
||||
function capitalizeFirstLetter(word) {
|
||||
return (word).charAt(0).toUpperCase() + (word).slice(1);
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Get the file name from the command line arguments
|
||||
const fileName = process.argv[2];
|
||||
|
||||
// Check if a file name is provided
|
||||
if (!fileName) {
|
||||
console.error('Please provide a file name.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Define the directory path
|
||||
const directoryPath = path.join('src', 'types');
|
||||
|
||||
// Ensure the directory exists
|
||||
if (!fs.existsSync(directoryPath)) {
|
||||
fs.mkdirSync(directoryPath, { recursive: true }); // Create the directory if it doesn't exist
|
||||
}
|
||||
|
||||
const FileContainer = `
|
||||
|
||||
import { Nullable } from "./App";
|
||||
|
||||
// Define the ${capitalizeFirstLetter(fileName)} interface
|
||||
|
||||
export interface ${capitalizeFirstLetter(fileName)} {
|
||||
id: number;
|
||||
name: string;
|
||||
image: string;
|
||||
}
|
||||
|
||||
export interface InitialValues {
|
||||
id: number;
|
||||
name: string;
|
||||
image: string;
|
||||
}
|
||||
|
||||
export type ${capitalizeFirstLetter(fileName)}InitialValues = Partial<Nullable<InitialValues>>;
|
||||
|
||||
`;
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(directoryPath, `${capitalizeFirstLetter(fileName)}.ts`),
|
||||
FileContainer
|
||||
);
|
||||
|
||||
console.log(`File "${fileName}" generated successfully.`);
|
||||
|
||||
function capitalizeFirstLetter(word) {
|
||||
return word.charAt(0).toUpperCase() + word.slice(1);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user