diff --git a/.env.pymeca.example b/.env.pymeca.example index 8aa5879..b18e182 100644 --- a/.env.pymeca.example +++ b/.env.pymeca.example @@ -1,26 +1,22 @@ -# MECA_BLOCKCHAIN_RPC_URL=http://host.docker.internal:9000 -# MECA_TASK_EXECUTOR_URL=http://meca-executor-1:2591 +MECA_BLOCKCHAIN_RPC_URL=http://host.docker.internal:9000 +MECA_TASK_EXECUTOR_URL=http://meca-executor-1:2591 -# # use 1 or more of the following +# Host +MECA_TASK_EXECUTOR_URL= +MECA_IPFS_HOST= +MECA_IPFS_PORT= +MECA_HOST_PRIVATE_KEY= +MECA_HOST_ENCRYPTION_PRIVATE_KEY= -# # Host -# MECA_BLOCKCHAIN_RPC_URL= -# MECA_TASK_EXECUTOR_URL= -# MECA_IPFS_HOST= -# MECA_IPFS_PORT= -# MECA_HOST_PRIVATE_KEY= -# MECA_HOST_ENCRYPTION_PRIVATE_KEY= +# Task developer +MECA_IPFS_API_HOST= +MECA_IPFS_API_PORT= +MECA_DEV_PRIVATE_KEY= -# # Task developer -# MECA_BLOCKCHAIN_RPC_URL= -# MECA_IPFS_API_HOST= -# MECA_IPFS_API_PORT= -# MECA_DEV_PRIVATE_KEY= +# User +MECA_USER_PRIVATE_KEY= -# # User -# MECA_BLOCKCHAIN_RPC_URL= -# MECA_USER_PRIVATE_KEY= +# Tower +MECA_TOWER_PRIVATE_KEY= -# # Tower -# MECA_BLOCKCHAIN_RPC_URL= -# MECA_TOWER_PRIVATE_KEY= +MECA_DAO_CONTRACT_ADDRESS= diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..a2e36b2 --- /dev/null +++ b/.npmignore @@ -0,0 +1 @@ +.env.pymeca diff --git a/docs/source/_static/images/dashboard.png b/docs/source/_static/images/dashboard.png index ead3d9b..b903bd9 100644 Binary files a/docs/source/_static/images/dashboard.png and b/docs/source/_static/images/dashboard.png differ diff --git a/docs/source/_static/images/tasks.png b/docs/source/_static/images/tasks.png index b0ca0eb..3ef0d29 100644 Binary files a/docs/source/_static/images/tasks.png and b/docs/source/_static/images/tasks.png differ diff --git a/docs/source/_static/images/towers.png b/docs/source/_static/images/towers.png index 0cd9c3a..3859126 100644 Binary files a/docs/source/_static/images/towers.png and b/docs/source/_static/images/towers.png differ diff --git a/docs/source/index.rst b/docs/source/index.rst index bcb74c0..ce926db 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -20,3 +20,16 @@ The guides here help you use MECA Desktop. You can also contribute to the projec pages/developers/developer_guide pages/developers/task_executor + +.. toctree:: + :maxdepth: 1 + :caption: Links + + Pymeca github + Meca github + Meca Desktop github + Pymeca documentation + Meca documentation + Meca Desktop documentation + Youtube + Technical guide video diff --git a/src/main/dockerIntegration.ts b/src/main/dockerIntegration.ts index 57e4dae..1e4233b 100644 --- a/src/main/dockerIntegration.ts +++ b/src/main/dockerIntegration.ts @@ -7,7 +7,7 @@ import { IpcMainEvent } from 'electron'; import { ContainerPort, ImageName } from '../common/dockerNames'; import Channels from '../common/channels'; import { getIpfsFilesDir } from './ipfsIntegration'; -import { getElectronStore, getElectronStoreFromKey } from './electronStore'; +import { getElectronStoreFromKey } from './electronStore'; const docker = new Dockerode(); @@ -31,22 +31,18 @@ const rawPymecaEnvKeys: string[] = [ 'MECA_DEV_PRIVATE_KEY', 'MECA_USER_PRIVATE_KEY', 'MECA_TOWER_PRIVATE_KEY', + 'MECA_DAO_CONTRACT_ADDRESS', ]; // get the env details export const getPymecaEnv = (): string[] => { - const pymecaEnv: string[] = []; - - for (const key of rawPymecaEnvKeys) { + return Object(rawPymecaEnvKeys).map((key: string) => { const value = getElectronStoreFromKey(key); - if (value !== null && value !== undefined) { - pymecaEnv.push(`${key}=${value}`) - } else { - pymecaEnv.push(`${key}=`) + if (value === null || value === undefined) { + return `${key}=`; } - } - - return pymecaEnv; + return `${key}=${value}`; + }); } export const removeDockerContainer = async ( diff --git a/src/renderer/components/auth/Login.tsx b/src/renderer/components/auth/Login.tsx index 2d0b1bd..d571929 100644 --- a/src/renderer/components/auth/Login.tsx +++ b/src/renderer/components/auth/Login.tsx @@ -22,9 +22,16 @@ import { LoginFormSchema, LoginFormValues, } from '../componentsCommon/FormSchema'; +import ErrorDialog from '../componentsCommon/ErrorDialogue'; const Login = () => { const [isLoading, setIsLoading] = useState(false); + const [errorMessage, setErrorMessage] = useState(''); + const [errorDialogOpen, setErrorDialogOpen] = useState(false); + + const handleCloseErrorDialog = () => { + setErrorDialogOpen(false); + }; async function setup() { try { @@ -85,6 +92,11 @@ const Login = () => { return ( + {isLoading ? ( { gpus: 0, }) ); + window.electron.store.set('taskList', JSON.stringify(initialTaskList)); } catch (keyPairGenerationError) { throw keyPairGenerationError; } diff --git a/src/renderer/components/componentsCommon/FormSchema.tsx b/src/renderer/components/componentsCommon/FormSchema.tsx index e93f728..cfd2655 100644 --- a/src/renderer/components/componentsCommon/FormSchema.tsx +++ b/src/renderer/components/componentsCommon/FormSchema.tsx @@ -29,6 +29,7 @@ export const InitialLoginFormValues: LoginFormValues = { MECA_DEV_PRIVATE_KEY: process.env.MECA_DEV_PRIVATE_KEY || '', MECA_USER_PRIVATE_KEY: process.env.MECA_USER_PRIVATE_KEY || '', MECA_TOWER_PRIVATE_KEY: process.env.MECA_TOWER_PRIVATE_KEY || '', + MECA_DAO_CONTRACT_ADDRESS: process.env.MECA_DAO_CONTRACT_ADDRESS || '', }; export interface LoginFormValues { @@ -39,6 +40,7 @@ export interface LoginFormValues { IPFS_NODE_URL: string; MECA_BLOCKCHAIN_RPC_URL: string; MECA_TASK_EXECUTOR_URL: string; + MECA_DAO_CONTRACT_ADDRESS: string; // host MECA_IPFS_HOST: string; MECA_IPFS_PORT: number; @@ -76,6 +78,7 @@ export const LoginFormSchema = Yup.object({ MECA_TASK_EXECUTOR_URL: Yup.string() .required('Task executor URL required!') .default('http://meca-executor-1:2591'), + MECA_DAO_CONTRACT_ADDRESS: Yup.string(), // host MECA_IPFS_HOST: Yup.string() .required('IPFS host required!') diff --git a/src/renderer/components/tasks/TasksManagement.tsx b/src/renderer/components/tasks/TasksManagement.tsx index dd0805d..0d3ecef 100644 --- a/src/renderer/components/tasks/TasksManagement.tsx +++ b/src/renderer/components/tasks/TasksManagement.tsx @@ -11,7 +11,7 @@ import { import RefreshIcon from '@mui/icons-material/Refresh'; import { ComputingType, Task } from 'renderer/utils/dataTypes'; import { getTaskListFromContract } from 'renderer/services/TaskContractService'; -import { cid_from_sha256 } from 'renderer/services/PymecaService'; +import { cid_from_sha256, initActor } from 'renderer/services/PymecaService'; import { retrieveIPFSFolderMetadata } from 'renderer/services/IPFSService'; import TaskCard from './TaskCard'; import SortWidget from './SortWidget'; @@ -49,6 +49,7 @@ const TasksManagement: React.FC = () => { const indexOfFirstTask = indexOfLastTask - tasksPerPage; const handleRefresh = () => { + initActor('host'); getTaskListFromContract() .then(async (rawTasks) => { if (!rawTasks || rawTasks.length === 0) { diff --git a/src/renderer/redux/reducers.tsx b/src/renderer/redux/reducers.tsx index 82f2aa1..5ddfce8 100644 --- a/src/renderer/redux/reducers.tsx +++ b/src/renderer/redux/reducers.tsx @@ -47,7 +47,7 @@ const initialDataEntry: DataEntry = { transaction_id: '', }; -const initialTaskList: TaskList = { +export const initialTaskList: TaskList = { built: [], tested: [], activated: [],