Skip to content

Commit

Permalink
wip: versions visibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Oct 13, 2024
1 parent 9c8085a commit d72d449
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 114 deletions.
68 changes: 5 additions & 63 deletions webui/src/Modules/ModuleManagePanel.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,12 @@
import React, { useCallback, useContext, useEffect, useMemo, useState, version } from 'react'
import { ConnectionsContext, LoadingRetryOrError, socketEmitPromise } from '../util.js'
import { CRow, CCol, CButton, CFormSelect, CAlert } from '@coreui/react'
import { TextInputField } from '../Components/index.js'
import { nanoid } from 'nanoid'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import {
faLock,
faPlug,
faPlus,
faQuestion,
faQuestionCircle,
faStar,
faSync,
faToiletsPortable,
faTrash,
faWarning,
} from '@fortawesome/free-solid-svg-icons'
import { isLabelValid } from '@companion-app/shared/Label.js'
import { ClientConnectionConfig } from '@companion-app/shared/Model/Common.js'
import { useOptionsAndIsVisible } from '../Hooks/useOptionsAndIsVisible.js'
import { ExtendedInputField } from '@companion-app/shared/Model/Options.js'
import React, { useContext, useEffect, useState } from 'react'
import { socketEmitPromise } from '../util.js'
import { CRow, CCol } from '@coreui/react'
import { RootAppStoreContext } from '../Stores/RootAppStore.js'
import { observer } from 'mobx-react-lite'
import type {
ModuleVersionInfo,
ModuleVersionMode,
NewClientModuleInfo,
NewClientModuleVersionInfo2,
} from '@companion-app/shared/Model/ModuleInfo.js'
import { ModuleStoreModuleInfoStore, ModuleStoreModuleInfoVersion } from '@companion-app/shared/Model/ModulesStore.js'
import type { NewClientModuleInfo, NewClientModuleVersionInfo2 } from '@companion-app/shared/Model/ModuleInfo.js'
import { ModuleStoreModuleInfoStore } from '@companion-app/shared/Model/ModulesStore.js'
import { RefreshModuleInfo } from './RefreshModuleInfo.js'
import semver from 'semver'
import { faDochub } from '@fortawesome/free-brands-svg-icons'
import { toJS } from 'mobx'
import { LastUpdatedTimestamp } from './LastUpdatedTimestamp.js'
import { isModuleApiVersionCompatible } from '@companion-app/shared/ModuleApiVersionCheck.js'
import { ModuleVersionsTable } from './ModuleVersionsTable.js'
import { CustomModuleVersionsTable } from './CustomModuleVersionsTable.js'

Expand Down Expand Up @@ -88,38 +60,8 @@ const ModuleManagePanelInner = observer(function ModuleManagePanelInner({
}: ModuleManagePanelInnerProps) {
const { socket } = useContext(RootAppStoreContext)

const [error, setError] = useState<string | null>(null)
const [reloadToken, setReloadToken] = useState(nanoid())

const moduleStoreInfo = useModuleStoreInfo(moduleId)

const doRetryConfigLoad = useCallback(() => setReloadToken(nanoid()), [])

/**
* Store/builtin Versions table
* sorted by version number
* Install/uninstall button
* plug icon indicating in use (hover for a count)
* Icon indicating latest stable
* Icon indicating latest prerelease
* Indicate prerelease in version number field?
* Options to filter to just installed/available
*
* Above table, show when info last refreshed, and a button to refresh
* quick option to install latest?
*
* filter by installed/available with extra option to show deprecated (default hidden)
* also option to show prerelease (default hidden)
*
* should stable and prerelease be separate?
*
*
* Separate table of 'custom' modules?
* I am tempted to combine them, but as numbers can collide will that be confusing?
*
*
*/

return (
<div>
<h5>
Expand Down
106 changes: 55 additions & 51 deletions webui/src/Modules/ModuleVersionsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback, useContext, useState } from 'react'
import { socketEmitPromise } from '../util.js'
import { CButton } from '@coreui/react'
import { CButton, CButtonGroup } from '@coreui/react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import {
faLock,
Expand All @@ -19,6 +19,7 @@ import { ModuleStoreModuleInfoStore, ModuleStoreModuleInfoVersion } from '@compa
import semver from 'semver'
import { isModuleApiVersionCompatible } from '@companion-app/shared/ModuleApiVersionCheck.js'
import { ModuleVersionUsageIcon } from './ModuleVersionUsageIcon.js'
import { useTableVisibilityHelper, VisibilityButton } from '../Components/TableVisibility.js'

interface ModuleVersionsTableProps {
moduleInfo: NewClientModuleInfo
Expand All @@ -45,66 +46,62 @@ export const ModuleVersionsTable = observer(function ModuleVersionsTable({

const allVersionNumbers = Array.from(allVersionsSet).sort((a, b) => semver.compare(b, a))

const visibleVersions = useTableVisibilityHelper<VisibleVersionsState>(
`modules_visible_versions:${moduleInfo.baseInfo.id}`,
{
availableStable: true,
availableDeprecated: false,
availablePrerelease: false,
}
)

return (
<table className="table-tight table-responsive-sm">
<thead>
<tr>
<th>Version</th>
<th>&nbsp;</th>
<th colSpan={3} className="fit">
{/* <CButtonGroup style={{ float: 'right', margin: 0 }}>
<CButton
size="sm"
color="secondary"
style={{
backgroundColor: 'white',
opacity: visibleModules.dev ? 1 : 0.4,
padding: '1px 5px',
color: 'black',
}}
onClick={doToggleDev}
>
Dev
</CButton>
<CButton
size="sm"
color="success"
style={{ opacity: visibleModules.builtin ? 1 : 0.4, padding: '1px 5px' }}
onClick={doToggleBuiltin}
>
Builtin
</CButton>
<CButton
color="warning"
size="sm"
style={{ opacity: visibleModules.store ? 1 : 0.4, padding: '1px 5px' }}
onClick={doToggleStore}
>
Store
</CButton>
<CButton
color="danger"
size="sm"
style={{ opacity: visibleModules.custom ? 1 : 0.4, padding: '1px 5px' }}
onClick={doToggleCustom}
>
Custom
</CButton>
</CButtonGroup> */}
<CButtonGroup className="table-header-buttons">
<VisibilityButton {...visibleVersions} keyId="availableStable" color="success" label="Stable" />
<VisibilityButton {...visibleVersions} keyId="availablePrerelease" color="warning" label="Prerelease" />
<VisibilityButton {...visibleVersions} keyId="availableDeprecated" color="danger" label="Deprecated" />
</CButtonGroup>
</th>
</tr>
</thead>
<tbody>
{allVersionNumbers.map((versionId) => (
<ModuleVersionRow
key={versionId}
moduleId={moduleInfo.baseInfo.id}
versionId={versionId}
storeInfo={storeModuleVersions.get(versionId)}
installedInfo={installedModuleVersions.get(versionId)}
isLatestStable={!!moduleInfo.stableVersion && moduleInfo.stableVersion.versionId === versionId}
isLatestPrerelease={!!moduleInfo.prereleaseVersion && moduleInfo.prereleaseVersion.versionId === versionId}
/>
))}
{allVersionNumbers.map((versionId) => {
const storeInfo = storeModuleVersions.get(versionId)
const installedInfo = installedModuleVersions.get(versionId)
if (storeInfo) {
// Hide based on visibility settings
if (storeInfo.deprecationReason && !visibleVersions.visiblity.availableDeprecated) return null
if (storeInfo.isPrerelease && !visibleVersions.visiblity.availablePrerelease) return null

if (
!storeInfo.deprecationReason &&
!storeInfo.isPrerelease &&
!installedInfo &&
!visibleVersions.visiblity.availableStable
)
return null
}

return (
<ModuleVersionRow
key={versionId}
moduleId={moduleInfo.baseInfo.id}
versionId={versionId}
storeInfo={storeInfo}
installedInfo={installedInfo}
isLatestStable={!!moduleInfo.stableVersion && moduleInfo.stableVersion.versionId === versionId}
isLatestPrerelease={
!!moduleInfo.prereleaseVersion && moduleInfo.prereleaseVersion.versionId === versionId
}
/>
)
})}
{/* {hiddenCount > 0 && (
<tr>
<td colSpan={4} style={{ padding: '10px 5px' }}>
Expand All @@ -118,6 +115,12 @@ export const ModuleVersionsTable = observer(function ModuleVersionsTable({
)
})

interface VisibleVersionsState {
availableStable: boolean
availableDeprecated: boolean
availablePrerelease: boolean
}

interface ModuleVersionRowProps {
moduleId: string
versionId: string
Expand Down Expand Up @@ -153,6 +156,7 @@ const ModuleVersionRow = observer(function ModuleVersionRow({
</td>
<td>
{versionId}
{storeInfo?.isPrerelease && <FontAwesomeIcon icon={faQuestion} title="Prerelease" />}
{storeInfo?.deprecationReason && <FontAwesomeIcon icon={faWarning} title="Deprecated" />}
</td>
<td>{storeInfo?.releasedAt ? new Date(storeInfo?.releasedAt).toDateString() : 'Unknown'}</td>
Expand Down

0 comments on commit d72d449

Please sign in to comment.