From d8564eaecb2c58a9498827c6d8034fd5a266f766 Mon Sep 17 00:00:00 2001 From: vipinpaul Date: Wed, 28 Aug 2024 19:04:01 +0530 Subject: [PATCH] Re-designed the flow and auto-updating the existing books & chapters in the scope from the backend --- .../ProjectManagement/ProjectManagement.js | 124 ++++++++++-------- .../scope-management/BookItem.jsx | 9 +- .../scope-management/ScopeManagement.jsx | 43 +++--- .../utils/readProjectScope.js | 20 ++- .../utils/updateBurritoScope.js | 24 ++++ 5 files changed, 143 insertions(+), 77 deletions(-) create mode 100644 renderer/src/components/ProjectManagement/utils/updateBurritoScope.js diff --git a/renderer/src/components/ProjectManagement/ProjectManagement.js b/renderer/src/components/ProjectManagement/ProjectManagement.js index ec5efabf..91c35402 100644 --- a/renderer/src/components/ProjectManagement/ProjectManagement.js +++ b/renderer/src/components/ProjectManagement/ProjectManagement.js @@ -3,22 +3,21 @@ import React, { useRef, Fragment, useEffect, useCallback, + useState, } from 'react'; import PropTypes from 'prop-types'; import { Dialog, Transition } from '@headlessui/react'; import { useTranslation } from 'react-i18next'; -import updateTranslationSB from '@/core/burrito/updateTranslationSB'; -import updateObsSB from '@/core/burrito/updateObsSB'; import { SnackBar } from '@/components/SnackBar'; // import useSystemNotification from '@/components/hooks/useSystemNotification'; // import { LoadingSpinner } from '@/components/LoadingSpinner'; -import ConfirmationModal from '@/layouts/editor/ConfirmationModal'; +// import ConfirmationModal from '@/layouts/editor/ConfirmationModal'; import CloseIcon from '@/illustrations/close-button-black.svg'; import * as logger from '../../logger'; -import burrito from '../../lib/BurritoTemplate.json'; import ScopeManagement from './scope-management/ScopeManagement'; import { readProjectScope } from './utils/readProjectScope'; import { LoadingSpinner } from '../LoadingSpinner'; +import { updateBurritoScope } from './utils/updateBurritoScope'; export default function ProjectMangement(props) { const { @@ -28,50 +27,19 @@ export default function ProjectMangement(props) { } = props; const { t } = useTranslation(); const cancelButtonRef = useRef(null); - const [valid, setValid] = React.useState(false); - const [snackBar, setOpenSnackBar] = React.useState(false); - const [snackText, setSnackText] = React.useState(''); - const [notify, setNotify] = React.useState(); - const [openModal, setOpenModal] = React.useState(false); - const [checkText, setCheckText] = React.useState(false); - const [totalExported, setTotalExported] = React.useState(0); - const [totalExports, setTotalExports] = React.useState(0); - const [exportStart, setExportstart] = React.useState(false); + const [snackBar, setOpenSnackBar] = useState(false); + const [snackText, setSnackText] = useState(''); + const [notify, setNotify] = useState(); + const [currentScope, setCurrentScope] = useState({}); + const [metadata, setMetadata] = useState(''); + const [loading, setLoading] = useState(false); + const [backendScope, setBackendScope] = useState({}); - const [metadata, setMetadata] = React.useState(''); - const [loading, setLoading] = React.useState(false); - - // const { pushNotification } = useSystemNotification(); - - function resetExportProgress() { - logger.debug('ExportProjectPopUp.js', 'reset Export Progress'); - if (!exportStart) { - setTotalExported(0); - setTotalExports(0); - setExportstart(false); - } - } - - function close() { - if (!exportStart) { - logger.debug('ExportProjectPopUp.js', 'Closing the Dialog Box'); - resetExportProgress(); // reset export - closePopUp(false); - setValid(false); - setMetadata({}); - setCheckText(false); - } - } - - const updateBurritoVersion = (username) => { - logger.debug('ExportProjectPopUp.js', 'Inside updateBurritoVersion'); - setTotalExported(1); // 1 step of 2 finished - if (project?.type === 'Text Translation') { - updateTranslationSB(username, project, openModal); - } else if (project?.type === 'OBS') { - updateObsSB(username, project, openModal); - } - setOpenModal(false); + const close = () => { + logger.debug('ProjectMangement.js', 'Closing the Dialog Box'); + setOpenSnackBar(true); + closePopUp(false); + setMetadata({}); }; // load Metadata of the project @@ -80,13 +48,61 @@ export default function ProjectMangement(props) { setLoading(true); const projectFullName = `${project?.name}_${project?.id?.[0]}`; const projectMeta = await readProjectScope(projectFullName); - setMetadata(projectMeta); + setMetadata(projectMeta.metadata); + setBackendScope(projectMeta.scope); } catch (err) { console.error('Read Meta : ', err); } finally { setLoading(false); } }, [project]); + function compareNumbers(a, b) { + return a - b; + } + const handleProject = () => { + logger.debug('ProjectMangement.js', 'Inside updateBurrito'); + let mergedScope = currentScope; + // Merge both existing and new scope, if any scope difference exists + if (Object.keys(backendScope).length > 0) { + Object.entries(backendScope).forEach((book) => { + // Checking whether the book in scope is available in currentscope + if (currentScope[book[0]]) { + // merging the chapters of existing and selected books + const scopeSet = backendScope[book[0]]; + const currentSet = currentScope[book[0]]; + const arr = [...scopeSet, ...currentSet]; + const mergedArr = [...new Set(arr)]; + mergedScope = { ...mergedScope, [book[0]]: mergedArr.sort(compareNumbers) }; + } else { + mergedScope = { ...mergedScope, [book[0]]: Object.values(backendScope[book[0]]) }; + } + }); + } + metadata.type.flavorType.currentScope = mergedScope; + const projectFullName = `${project?.name}_${project?.id?.[0]}`; + updateBurritoScope(projectFullName, metadata).then(() => { + setNotify('success'); + setSnackText('Scope updated successfully!'); + close(); + }); + }; + + // const handleProject = () => { + // metadata.type.flavorType.currentScope = currentScope; + // const projectFullName = `${project?.name}_${project?.id?.[0]}`; + // // updateBurritoScope checks whether user has removed anything (Book(s)/Chapter(s)) from the existing scope or not + // updateBurritoScope(projectFullName, metadata, 'difference').then((value) => { + // console.log('scope', value); + // if (Object.keys(value).length > 0) { + // // Has some change so merge is required + // setScopeDiff(value); + // // setOpenModal(true); + // } else { + // // nothing been removed by the user + // updateBurrito(); + // } + // }); + // }; useEffect(() => { getProjectMetadata(); @@ -138,7 +154,7 @@ export default function ProjectMangement(props) {
- {loading ? : } + {loading ? : }
@@ -154,7 +170,7 @@ export default function ProjectMangement(props) { type="button" aria-label="edit-language" className=" bg-success w-28 h-8 border-color-success rounded uppercase text-white text-xs shadow focus:outline-none" - onClick={() => console.log('Apply scope change clicked')} + onClick={() => handleProject()} > Apply @@ -174,16 +190,16 @@ export default function ProjectMangement(props) { setSnackText={setSnackText} error={notify} /> - updateBurritoVersion(metadata.username, metadata.fs, metadata.path, metadata.folder) + () => updateBurrito() } - /> + /> */} ); } diff --git a/renderer/src/components/ProjectManagement/scope-management/BookItem.jsx b/renderer/src/components/ProjectManagement/scope-management/BookItem.jsx index e97ed1ca..ccf8f222 100644 --- a/renderer/src/components/ProjectManagement/scope-management/BookItem.jsx +++ b/renderer/src/components/ProjectManagement/scope-management/BookItem.jsx @@ -1,18 +1,19 @@ +/* eslint-disable no-nested-ternary */ import React from 'react'; import BookButton from '../Common/Button/BookButton'; import XMark from '@/icons/Xelah/XMark.svg'; function BookItem({ - book, handleSelectBook, handleRemoveScope, isInScope, + book, handleSelectBook, handleRemoveScope, isInScope, disable, }) { return (
handleSelectBook(e, book)} >
handleRemoveScope(e, book)} /> diff --git a/renderer/src/components/ProjectManagement/scope-management/ScopeManagement.jsx b/renderer/src/components/ProjectManagement/scope-management/ScopeManagement.jsx index ba504ff6..82b03001 100644 --- a/renderer/src/components/ProjectManagement/scope-management/ScopeManagement.jsx +++ b/renderer/src/components/ProjectManagement/scope-management/ScopeManagement.jsx @@ -23,10 +23,11 @@ const ToggleChapterOptions = [ { key: 'none', name: 'Deselect' }, ]; -function ScopeManagement({ metadata }) { +function ScopeManagement({ + metadata, currentScope, setCurrentScope, backendScope, +}) { const [bookFilter, setBookFilter] = useState(''); const [chapterFilter, setChapterFilter] = useState(''); - const [currentScope, setCurrentScope] = useState({}); const [selectedChaptersSet, setSelectedChaptersSet] = useState(new Set([])); const { @@ -51,7 +52,7 @@ function ScopeManagement({ metadata }) { }); console.log('BOOK ============>', { - bookName, bookId, metadata, currentScope, + bookName, bookId, metadata, currentScope, backendScope, }); const handleChangeBookToggle = (event) => { @@ -191,7 +192,7 @@ function ScopeManagement({ metadata }) {
- {bookList?.slice(0, 39)?.map((book) => { + {backendScope && bookList?.slice(0, 39)?.map((book) => { const isScope = book?.key?.toUpperCase() in currentScope; return ( ); })} @@ -208,7 +210,7 @@ function ScopeManagement({ metadata }) {
- {bookList?.slice(39)?.map((book) => { + {backendScope && bookList?.slice(39)?.map((book) => { const isScope = book?.key?.toUpperCase() in currentScope; return ( ); })}
- - -

- Chapter Selection : - {bookName} -

- -
+ {bookName + && ( + +

+ Chapter Selection : + {bookName} +

+ +
+ )}
@@ -268,11 +273,13 @@ function ScopeManagement({ metadata }) {
{chapterList?.map(({ key, name }) => { const isInScope = selectedChaptersSet.has(key); + const disable = backendScope[bookId.toUpperCase()]?.includes(key); return ( handleChapterSelection(e, name)} key={key} - className={`border min-w-8 text-center ${isInScope ? 'bg-primary text-white font-medium' : ''}`} + // eslint-disable-next-line no-nested-ternary + className={`border min-w-8 text-center ${disable ? 'bg-gray-400' : isInScope ? 'bg-primary text-white font-medium' : ''}`} > {name} diff --git a/renderer/src/components/ProjectManagement/utils/readProjectScope.js b/renderer/src/components/ProjectManagement/utils/readProjectScope.js index e501bb2b..04559c9b 100644 --- a/renderer/src/components/ProjectManagement/utils/readProjectScope.js +++ b/renderer/src/components/ProjectManagement/utils/readProjectScope.js @@ -2,6 +2,22 @@ import localForage from 'localforage'; import * as logger from '../../../logger'; import packageInfo from '../../../../../package.json'; +const getDirectories = (readdirSync, source) => readdirSync(source, { withFileTypes: true }) + .filter((dirent) => dirent.isDirectory()) + .map((dirent) => dirent.name); + +// This function returns the Object of books & chapters which has atleast 1 audio file in it. +export const getScope = (project) => { + const path = require('path'); + const scope = {}; + const { readdirSync } = window.require('fs'); + const list = getDirectories(readdirSync, project); + list.forEach((book) => { + const chapters = getDirectories(readdirSync, path.join(project, book)); + scope[book] = chapters; + }); + return scope; +}; export const readProjectScope = async (projectName) => { try { logger.debug('readProjectScope.js', `In read metadata - ${projectName}`); @@ -17,8 +33,10 @@ export const readProjectScope = async (projectName) => { const metadataFile = await fs.readFileSync(filePath, 'utf-8'); if (metadataFile) { logger.debug('metadataFile.js', `read metadata file successfully - ${projectName}`); + const project = path.join(file, projectName, 'audio', 'ingredients'); + const backendScope = getScope(project); const json = await JSON.parse(metadataFile); - return json; + return { metadata: json, scope: backendScope }; } throw new Error(`failed to read settings file - ${projectName}`); } diff --git a/renderer/src/components/ProjectManagement/utils/updateBurritoScope.js b/renderer/src/components/ProjectManagement/utils/updateBurritoScope.js new file mode 100644 index 00000000..c7cb8985 --- /dev/null +++ b/renderer/src/components/ProjectManagement/utils/updateBurritoScope.js @@ -0,0 +1,24 @@ +import localForage from 'localforage'; +import * as logger from '../../../logger'; +import packageInfo from '../../../../../package.json'; + +export const updateBurritoScope = async (projectName, metadata) => { + try { + logger.debug('updateBurritoScope.js', `In update metadata - ${projectName}`); + const currentUser = await localForage.getItem('userProfile'); + const newpath = localStorage.getItem('userPath'); + const fs = window.require('fs'); + const path = require('path'); + const file = path.join(newpath, packageInfo.name, 'users', currentUser.username, 'projects'); + // Finally updating the scope in the metadata + const filePath = path.join(file, projectName, 'metadata.json'); + if (fs.existsSync(filePath)) { + fs.writeFileSync(filePath, JSON.stringify(metadata)); + return true; + } + throw new Error(`failed to read metadata file - ${projectName}`); + } catch (err) { + logger.error('updateBurritoScope.js', `read metadata file successfully - ${projectName}`); + throw new Error(err?.message || err); + } +};