finish refactor for inactive plugins, active plugins and plugin permissions

pull/5370/head
joseph izang 3 years ago
parent 60341df9c5
commit d1c833f1f7
  1. 71
      libs/remix-ui/plugin-manager/src/lib/components/permissions/permissionsSettings.tsx
  2. 105
      libs/remix-ui/plugin-manager/src/lib/components/rootView.tsx
  3. 27
      libs/remix-ui/plugin-manager/src/pluginManagerStateMachine.ts

@ -1,63 +1,31 @@
import React, { Fragment, useCallback, useEffect, useState } from 'react' import React, { Fragment, useCallback, useEffect, useState } from 'react'
import { PluginManagerSettings, PluginPermissions } from '../../../types' import { PluginManagerSettings, PluginPermissions } from '../../../types'
import { ModalDialog } from '@remix-ui/modal-dialog' import { ModalDialog } from '@remix-ui/modal-dialog'
import { RemixUiCheckbox } from '@remix-ui/checkbox'
import { useLocalStorage } from '../../useLocalStorage'
import { type } from 'os'
interface PermissionSettingsProps { interface PermissionSettingsProps {
pluginSettings: PluginManagerSettings pluginSettings: PluginManagerSettings
} }
type DisplayPermissions = {
controlPluginName: {
controlPluginAction: {
pluginName: {
allow: boolean
}
}
}
}
function PermisssionsSettings ({ pluginSettings }: PermissionSettingsProps) { function PermisssionsSettings ({ pluginSettings }: PermissionSettingsProps) {
/** /**
* Declare component local state * Declare component local state
*/ */
const [modalVisibility, setModalVisibility] = useState<boolean>(true) const [modalVisibility, setModalVisibility] = useState<boolean>(true)
const [permissions, setPermissions] = useState<PluginPermissions | null>( const [permissions] = useState<PluginPermissions | null>(
JSON.parse(localStorage.getItem('plugins/permissions') || '{}')) JSON.parse(localStorage.getItem('plugins/permissions') || '{}'))
const [showPermissions, setShowPermissions] = useState<PluginPermissions[]>([]) const [verifyPermission, setVerifyPermission] = useState(false)
const [akwaiPermission, setAkwaiPermission] = useState(false)
const closeModal = () => setModalVisibility(true) const closeModal = () => setModalVisibility(true)
const displayPermissions = useCallback(() => { const displayPermissions = useCallback(() => {
if (permissions && Object.length > 0) { if (permissions && Object.length > 0) {
setAkwaiPermission(true) setVerifyPermission(true)
} }
}, [permissions]) }, [permissions])
const getTopLevelPluginNames = useCallback(() => {
return Object.keys(permissions).map(pluginName => {
return pluginName
})
}, [permissions])
const getInnerPluginPermissionDetails = useCallback(() => {
const showPermissionsCopy = showPermissions
getTopLevelPluginNames().forEach(topLevelName => {
Object.keys(permissions[topLevelName]).forEach(functionName => {
Object.keys(permissions[topLevelName][functionName]).forEach(pluginName => {
showPermissionsCopy.push(permissions[topLevelName][functionName][pluginName])
setShowPermissions(showPermissionsCopy)
})
})
})
}, [getTopLevelPluginNames, permissions, showPermissions])
useEffect(() => { useEffect(() => {
getInnerPluginPermissionDetails()
displayPermissions() displayPermissions()
}, [displayPermissions, getInnerPluginPermissionDetails, permissions, showPermissions]) }, [displayPermissions, permissions])
console.log('fetched permissions', permissions) // console.log('fetched permissions', permissions)
function ShowPluginHeading ({ headingName }) { function ShowPluginHeading ({ headingName }) {
return ( return (
@ -79,13 +47,23 @@ function PermisssionsSettings ({ pluginSettings }: PermissionSettingsProps) {
functionName: string, functionName: string,
topLevelPluginName: string topLevelPluginName: string
}) { }) {
const [checkBoxState, setCheckBoxState] = useState(allow)
useEffect(() => {
}, [checkBoxState])
const handleCheckboxClick = () => {
setCheckBoxState(!checkBoxState)
}
return ( return (
<div className="form-group remixui_permissionKey"> <div className="form-group remixui_permissionKey">
<div className="remixui_checkbox"> <div className="remixui_checkbox">
<span className="mr-2"> <span className="mr-2">
<RemixUiCheckbox <input
onChange={() => {}} type="checkbox"
checked={allow} onChange={handleCheckboxClick}
checked={checkBoxState}
id={`permission-checkbox-${topLevelPluginName}-${functionName}-${pluginName}`} id={`permission-checkbox-${topLevelPluginName}-${functionName}-${pluginName}`}
aria-describedby={`module ${pluginName} asks permission for ${functionName}`} aria-describedby={`module ${pluginName} asks permission for ${functionName}`}
/> />
@ -98,6 +76,11 @@ function PermisssionsSettings ({ pluginSettings }: PermissionSettingsProps) {
</label> </label>
</span> </span>
</div> </div>
<i
onClick={() => pluginSettings.clearPersmission(pluginName, topLevelPluginName, functionName)}
className="fa fa-trash-alt"
data-id={`pluginManagerSettingsRemovePermission-${topLevelPluginName}-${functionName}-${topLevelPluginName}`}
/>
</div> </div>
) )
} }
@ -109,7 +92,7 @@ function PermisssionsSettings ({ pluginSettings }: PermissionSettingsProps) {
hide={modalVisibility} hide={modalVisibility}
title="Plugin Manager Permissions" title="Plugin Manager Permissions"
> >
{akwaiPermission ? (<h4 className="text-center">Current Permission Settings</h4>) : (<h4 className="text-center">No Permission requested yet.</h4>)} {verifyPermission ? (<h4 className="text-center">Current Permission Settings</h4>) : (<h4 className="text-center">No Permission requested yet.</h4>)}
<form className="remixui_permissionForm" data-id="pluginManagerSettingsPermissionForm"> <form className="remixui_permissionForm" data-id="pluginManagerSettingsPermissionForm">
<div className="border p-2"> <div className="border p-2">
{ {
@ -118,11 +101,11 @@ function PermisssionsSettings ({ pluginSettings }: PermissionSettingsProps) {
)) ))
} }
{ {
Object.keys(permissions).forEach(topName => { Object.keys(permissions).map(topName => {
Object.keys(permissions[topName]).map(funcName => { return Object.keys(permissions[topName]).map(funcName => {
return Object.keys(permissions[topName][funcName]).map(pluginName => ( return Object.keys(permissions[topName][funcName]).map(pluginName => (
<ShowCheckBox <ShowCheckBox
allow={permissions.fileManager.writeFile[pluginName].allow} allow={permissions[topName][funcName][pluginName].allow}
functionName={funcName} functionName={funcName}
pluginName={pluginName} pluginName={pluginName}
topLevelPluginName={topName} topLevelPluginName={topName}

@ -1,5 +1,5 @@
/* eslint-disable no-debugger */ /* eslint-disable no-debugger */
import React, { Fragment, useEffect, useState } from 'react' import React, { Fragment, useCallback, useEffect, useState } from 'react'
import ModuleHeading from './moduleHeading' import ModuleHeading from './moduleHeading'
import { ModalDialog } from '@remix-ui/modal-dialog' import { ModalDialog } from '@remix-ui/modal-dialog'
import { FormStateProps, PluginManagerComponent } from '../../types' import { FormStateProps, PluginManagerComponent } from '../../types'
@ -8,7 +8,7 @@ import PermisssionsSettings from './permissions/permissionsSettings'
import { Profile } from '@remixproject/plugin-utils' import { Profile } from '@remixproject/plugin-utils'
import ActivePluginCard from './ActivePluginCard' import ActivePluginCard from './ActivePluginCard'
import InactivePluginCard from './InactivePluginCard' import InactivePluginCard from './InactivePluginCard'
import { GetNewlyActivatedPlugins, PersistNewInactivesState } from '../../pluginManagerStateMachine' import { PersistNewInactivesState, RemoveActivatedPlugin } from '../../pluginManagerStateMachine'
const initialState: FormStateProps = { const initialState: FormStateProps = {
pname: 'test', pname: 'test',
@ -33,7 +33,10 @@ function RootView ({ pluginComponent }: RootViewProps) {
const [filterPlugins, setFilterPlugin] = useState('') const [filterPlugins, setFilterPlugin] = useState('')
const [activeP, setActiveP] = useState<Profile[]>([]) const [activeP, setActiveP] = useState<Profile[]>([])
const [inactiveP, setInactiveP] = useState<Profile[]>([]) const [inactiveP, setInactiveP] = useState<Profile[]>([])
const [triggerRefresh, setTriggerRefresh] = useState(false) // eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, setTriggerRefresh] = useState(false)
const [validInactiveProfiles] = useState<Profile[]>(JSON.parse(window.localStorage.getItem('updatedInactives')))
const [validActiveProfiles] = useState<Profile[]>(JSON.parse(window.localStorage.getItem('newActivePlugins')))
function pluginChangeHandler<P extends keyof FormStateProps> (formProps: P, value: FormStateProps[P]) { function pluginChangeHandler<P extends keyof FormStateProps> (formProps: P, value: FormStateProps[P]) {
setPlugin({ ...plugin, [formProps]: value }) setPlugin({ ...plugin, [formProps]: value })
} }
@ -52,52 +55,90 @@ function RootView ({ pluginComponent }: RootViewProps) {
setTriggerRefresh(true) setTriggerRefresh(true)
} }
useEffect(() => { const GetNewlyActivatedPlugins = useCallback((pluginComponent: PluginManagerComponent) => {
pluginComponent.getAndFilterPlugins(filterPlugins) // const profiles: Profile[] = JSON.parse(window.localStorage.getItem('newActivePlugins'))
// eslint-disable-next-line react-hooks/exhaustive-deps let isValid: boolean = false
}, [filterPlugins]) // eslint-disable-next-line no-debugger
debugger
useEffect(() => { pluginComponent.activeProfiles.forEach(profileName => {
if (pluginComponent.activePlugins && pluginComponent.activePlugins.length) { isValid = validActiveProfiles.some(profile => profile.name === profileName)
setActiveP(pluginComponent.activePlugins) })
} if (isValid) {
// if (pluginComponent.inactivePlugins && pluginComponent.inactivePlugins.length) { return validActiveProfiles
// setInactiveP(pluginComponent.inactivePlugins) } else {
// } const profiles = validActiveProfiles // make a copy of state and don't mutate state directly
const validInactiveProfiles: Profile[] = JSON.parse(window.localStorage.getItem('updatedInactives')) profiles.forEach(profile => {
if (validInactiveProfiles && validInactiveProfiles.length) { if (!pluginComponent.activeProfiles.includes(profile.name)) {
if (inactiveP.length > validInactiveProfiles.length) { RemoveActivatedPlugin(profile.name)
setInactiveP(validInactiveProfiles)
}
} }
if (pluginComponent.inactivePlugins && pluginComponent.inactivePlugins.length) { })
setInactiveP(pluginComponent.inactivePlugins) const newProfiles = JSON.parse(window.localStorage.getItem('newActivePlugins'))
return newProfiles
} }
}, [pluginComponent.activePlugins, pluginComponent.inactivePlugins, activeP, inactiveP, pluginComponent.activeProfiles, pluginComponent]) }, [validActiveProfiles])
useEffect(() => { useEffect(() => {
if (activeP.length === 0) { if (activeP.length === 0) {
const activeProfiles = GetNewlyActivatedPlugins() const activeProfiles = GetNewlyActivatedPlugins(pluginComponent)
if (activeProfiles !== null && activeProfiles.length) { if (activeProfiles !== null && activeProfiles.length) {
setActiveP(activeProfiles) setActiveP(activeProfiles)
} else { } else {
setActiveP(pluginComponent.activePlugins) setActiveP(pluginComponent.activePlugins)
} }
} }
}, [activeP, pluginComponent.activePlugins, syncInactiveProfiles]) }, [GetNewlyActivatedPlugins, activeP, pluginComponent, pluginComponent.activePlugins, syncInactiveProfiles])
useEffect(() => { useEffect(() => {
syncInactiveProfiles() pluginComponent.getAndFilterPlugins(filterPlugins)
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [inactiveP, triggerRefresh]) }, [filterPlugins])
useEffect(() => { useEffect(() => {
const validInactiveProfiles: Profile[] = JSON.parse(window.localStorage.getItem('updatedInactives')) if (pluginComponent.activePlugins && pluginComponent.activePlugins.length) {
if (validInactiveProfiles && validInactiveProfiles.length && setActiveP(pluginComponent.activePlugins)
inactiveP.length > validInactiveProfiles.length) { }
setInactiveP(validInactiveProfiles)
if (pluginComponent.inactivePlugins && pluginComponent.inactivePlugins.length) {
setInactiveP(pluginComponent.inactivePlugins)
}
let inactivesCopy = []
if (validInactiveProfiles && validInactiveProfiles.length) {
if (validActiveProfiles && validActiveProfiles.length) {
validActiveProfiles.forEach(active => {
inactivesCopy = validInactiveProfiles.filter(inactive => inactive.name !== active.name)
.filter(inactive => inactive.displayName !== active.displayName)
})
} }
}, [inactiveP, triggerRefresh]) console.log('inactivescopy length', validInactiveProfiles.length)
if (inactivesCopy.length) setInactiveP(validInactiveProfiles)
}
}, [pluginComponent.activePlugins, pluginComponent.inactivePlugins, pluginComponent.activeProfiles, pluginComponent, validInactiveProfiles, inactiveP.length, validActiveProfiles])
// useEffect(() => {
// if (validInactiveProfiles && validInactiveProfiles.length &&
// inactiveP.length > validInactiveProfiles.length) {
// setInactiveP(validInactiveProfiles)
// }
// let inactivesCopy = []
// if (validInactiveProfiles && validInactiveProfiles.length) {
// if (inactiveP.length > validInactiveProfiles.length) {
// if (validActiveProfiles && validActiveProfiles.length) {
// validActiveProfiles.forEach(active => {
// inactivesCopy = validInactiveProfiles.filter(inactive => inactive !== active)
// .filter(inactive => inactive.displayName !== active.displayName)
// })
// }
// console.log('inactivescopy length', validInactiveProfiles.length)
// if (inactivesCopy.length) setInactiveP(validInactiveProfiles)
// }
// }
// }, [inactiveP, triggerRefresh, validActiveProfiles, validInactiveProfiles])
// useEffect(() => {
// syncInactiveProfiles()
// // eslint-disable-next-line react-hooks/exhaustive-deps
// }, [inactiveP, triggerRefresh])
return ( return (
<Fragment> <Fragment>

@ -39,8 +39,9 @@ export async function PersistActivatedPlugin (pluginComponent: PluginManagerComp
const activatedPlugins: Profile[] = JSON.parse(persisted) const activatedPlugins: Profile[] = JSON.parse(persisted)
const newlyActivatedPlugins: Array<Profile> = [] const newlyActivatedPlugins: Array<Profile> = []
const defaultActivated = defaultActivatedPlugins.includes(newPlugin.name) === false
if (newPlugin) { if (newPlugin) {
if (defaultActivatedPlugins.includes(newPlugin.name) === false) { if (defaultActivated) {
// if this is true then we are sure that the profile name is in localStorage/workspace // if this is true then we are sure that the profile name is in localStorage/workspace
if (activatedPlugins && activatedPlugins.length && !activatedPlugins.includes(newPlugin)) { if (activatedPlugins && activatedPlugins.length && !activatedPlugins.includes(newPlugin)) {
await FetchAndPersistPlugin(pluginComponent, newPlugin, activatedPlugins) await FetchAndPersistPlugin(pluginComponent, newPlugin, activatedPlugins)
@ -83,12 +84,25 @@ export async function UpdateInactivePluginList (deactivatedPlugin: Profile, plug
return tempArray return tempArray
} }
export function GetNewlyActivatedPlugins () { export function GetNewlyActivatedPlugins (pluginComponent: PluginManagerComponent) {
const profiles = JSON.parse(window.localStorage.getItem('newActivePlugins')) const profiles: Profile[] = JSON.parse(window.localStorage.getItem('newActivePlugins'))
if (profiles && profiles.length > 0) { let isValid: boolean = false
// eslint-disable-next-line no-debugger
debugger
pluginComponent.activeProfiles.forEach(profileName => {
isValid = profiles.some(profile => profile.name === profileName)
})
if (isValid) {
return profiles return profiles
} else {
profiles.forEach(profile => {
if (!pluginComponent.activeProfiles.includes(profile.name)) {
RemoveActivatedPlugin(profile.name)
}
})
const newProfiles = JSON.parse(window.localStorage.getItem('newActivePlugins'))
return newProfiles
} }
return profiles
} }
async function FetchAndPersistPlugin (pluginComponent: PluginManagerComponent, newPlugin: Profile<any>, newlyActivatedPlugins: Profile<any>[]) { async function FetchAndPersistPlugin (pluginComponent: PluginManagerComponent, newPlugin: Profile<any>, newlyActivatedPlugins: Profile<any>[]) {
@ -111,9 +125,10 @@ export function RemoveActivatedPlugin (pluginName: string) {
} }
/** /**
* gets the latest list of inactive plugin profiles and persist them * Gets the latest list of inactive plugin profiles and persist them
* in local storage * in local storage
* @param inactivesList Array of inactive plugin profiles * @param inactivesList Array of inactive plugin profiles
* @returns {void}
*/ */
export function PersistNewInactivesState (inactivesList: Profile[]) { export function PersistNewInactivesState (inactivesList: Profile[]) {
if (inactivesList && inactivesList.length) { if (inactivesList && inactivesList.length) {

Loading…
Cancel
Save