feat: add extension profiles (#3914)
Co-authored-by: Vlad Stan <stan.v.vlad@gmail.com>
This commit is contained in:
co-authored by
Vlad Stan
parent
ce177a73b1
commit
748f458b8b
@@ -55,9 +55,10 @@ class GitHubRelease(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class Manifest(BaseModel):
|
class Manifest(BaseModel):
|
||||||
featured: list[str] = []
|
|
||||||
extensions: list[ExplicitRelease] = []
|
extensions: list[ExplicitRelease] = []
|
||||||
repos: list[GitHubRelease] = []
|
repos: list[GitHubRelease] = []
|
||||||
|
featured: list[str] = []
|
||||||
|
categories: dict[str, list[str]] = {}
|
||||||
|
|
||||||
|
|
||||||
class GitHubRepoRelease(BaseModel):
|
class GitHubRepoRelease(BaseModel):
|
||||||
@@ -308,7 +309,6 @@ class ExtensionRelease(BaseModel):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def fetch_release_details(cls, details_link: str) -> dict | None:
|
async def fetch_release_details(cls, details_link: str) -> dict | None:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
resp = await client.get(details_link)
|
resp = await client.get(details_link)
|
||||||
@@ -333,6 +333,7 @@ class ExtensionMeta(BaseModel):
|
|||||||
dependencies: list[str] = []
|
dependencies: list[str] = []
|
||||||
archive: str | None = None
|
archive: str | None = None
|
||||||
featured: bool = False
|
featured: bool = False
|
||||||
|
categories: list[str] = []
|
||||||
paid_features: str | None = None
|
paid_features: str | None = None
|
||||||
has_paid_release: bool = False
|
has_paid_release: bool = False
|
||||||
has_free_release: bool = False
|
has_free_release: bool = False
|
||||||
@@ -680,6 +681,11 @@ class InstallableExtension(BaseModel):
|
|||||||
|
|
||||||
meta = ext.meta or ExtensionMeta()
|
meta = ext.meta or ExtensionMeta()
|
||||||
meta.featured = ext.id in manifest.featured
|
meta.featured = ext.id in manifest.featured
|
||||||
|
meta.categories = [
|
||||||
|
category
|
||||||
|
for category, ext_ids in manifest.categories.items()
|
||||||
|
if ext.id in ext_ids
|
||||||
|
]
|
||||||
ext.meta = meta
|
ext.meta = meta
|
||||||
extension_list += [ext]
|
extension_list += [ext]
|
||||||
|
|
||||||
@@ -695,6 +701,11 @@ class InstallableExtension(BaseModel):
|
|||||||
ext.check_release_updates(release)
|
ext.check_release_updates(release)
|
||||||
meta = ext.meta or ExtensionMeta()
|
meta = ext.meta or ExtensionMeta()
|
||||||
meta.featured = ext.id in manifest.featured
|
meta.featured = ext.id in manifest.featured
|
||||||
|
meta.categories = [
|
||||||
|
category
|
||||||
|
for category, ext_ids in manifest.categories.items()
|
||||||
|
if ext.id in ext_ids
|
||||||
|
]
|
||||||
ext.meta = meta
|
ext.meta = meta
|
||||||
extension_list += [ext]
|
extension_list += [ext]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -292,7 +292,6 @@ async def api_deactivate_extension(ext_id: str) -> SimpleStatus:
|
|||||||
|
|
||||||
@extension_router.delete("/{ext_id}", dependencies=[Depends(check_admin)])
|
@extension_router.delete("/{ext_id}", dependencies=[Depends(check_admin)])
|
||||||
async def api_uninstall_extension(ext_id: str) -> SimpleStatus:
|
async def api_uninstall_extension(ext_id: str) -> SimpleStatus:
|
||||||
|
|
||||||
extension = await get_installed_extension(ext_id)
|
extension = await get_installed_extension(ext_id)
|
||||||
if not extension:
|
if not extension:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
@@ -567,6 +566,7 @@ async def extensions(account_id: AccountId = Depends(check_account_id_exists)):
|
|||||||
"shortDescription": ext.short_description,
|
"shortDescription": ext.short_description,
|
||||||
"stars": ext.stars,
|
"stars": ext.stars,
|
||||||
"isFeatured": ext.meta.featured if ext.meta else False,
|
"isFeatured": ext.meta.featured if ext.meta else False,
|
||||||
|
"categories": ext.meta.categories if ext.meta else [],
|
||||||
"dependencies": ext.meta.dependencies if ext.meta else "",
|
"dependencies": ext.meta.dependencies if ext.meta else "",
|
||||||
"isInstalled": ext.id in installed_exts_ids,
|
"isInstalled": ext.id in installed_exts_ids,
|
||||||
"hasDatabaseTables": next(
|
"hasDatabaseTables": next(
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -184,6 +184,7 @@ window.localisation.en = {
|
|||||||
release_notes: 'Release Notes',
|
release_notes: 'Release Notes',
|
||||||
activate_extension_details: 'Make extension available/unavailable for users',
|
activate_extension_details: 'Make extension available/unavailable for users',
|
||||||
featured: 'Featured',
|
featured: 'Featured',
|
||||||
|
categories: 'Categories',
|
||||||
all: 'All',
|
all: 'All',
|
||||||
only_admins_can_install: '(Only admin accounts can install extensions)',
|
only_admins_can_install: '(Only admin accounts can install extensions)',
|
||||||
only_admins_can_create_extensions:
|
only_admins_can_create_extensions:
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ window.PageExtensions = {
|
|||||||
tab: 'installed',
|
tab: 'installed',
|
||||||
manageExtensionTab: 'releases',
|
manageExtensionTab: 'releases',
|
||||||
filteredExtensions: [],
|
filteredExtensions: [],
|
||||||
|
categories: new Set(),
|
||||||
updatableExtensions: [],
|
updatableExtensions: [],
|
||||||
showUninstallDialog: false,
|
showUninstallDialog: false,
|
||||||
showManageExtensionDialog: false,
|
showManageExtensionDialog: false,
|
||||||
@@ -106,6 +107,10 @@ window.PageExtensions = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isCategoryTab = !['installed', 'all', 'featured'].includes(tab)
|
||||||
|
const isInSelectedCategory = extension =>
|
||||||
|
extension.categories?.includes(tab) ?? false
|
||||||
|
|
||||||
this.filteredExtensions = this.extensions
|
this.filteredExtensions = this.extensions
|
||||||
.filter(e => (tab === 'all' ? !e.isInstalled : true))
|
.filter(e => (tab === 'all' ? !e.isInstalled : true))
|
||||||
.filter(e => (tab === 'installed' ? e.isInstalled : true))
|
.filter(e => (tab === 'installed' ? e.isInstalled : true))
|
||||||
@@ -113,6 +118,7 @@ window.PageExtensions = {
|
|||||||
tab === 'installed' ? (e.isActive ? true : !!this.g.user.admin) : true
|
tab === 'installed' ? (e.isActive ? true : !!this.g.user.admin) : true
|
||||||
)
|
)
|
||||||
.filter(e => (tab === 'featured' ? e.isFeatured : true))
|
.filter(e => (tab === 'featured' ? e.isFeatured : true))
|
||||||
|
.filter(e => (isCategoryTab ? isInSelectedCategory(e) : true))
|
||||||
.filter(extensionNameContains(term))
|
.filter(extensionNameContains(term))
|
||||||
.map(e => ({
|
.map(e => ({
|
||||||
...e,
|
...e,
|
||||||
@@ -832,6 +838,9 @@ window.PageExtensions = {
|
|||||||
async fetchAllExtensions() {
|
async fetchAllExtensions() {
|
||||||
try {
|
try {
|
||||||
const {data} = await LNbits.api.request('GET', `/api/v1/extension/all`)
|
const {data} = await LNbits.api.request('GET', `/api/v1/extension/all`)
|
||||||
|
data.forEach(ext => {
|
||||||
|
ext.categories?.forEach(category => this.categories.add(category))
|
||||||
|
})
|
||||||
return data
|
return data
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(error)
|
console.warn(error)
|
||||||
|
|||||||
@@ -7,7 +7,29 @@
|
|||||||
<q-tabs v-model="tab" active-color="primary" align="left">
|
<q-tabs v-model="tab" active-color="primary" align="left">
|
||||||
<q-tab name="installed" :label="$t('installed')"></q-tab>
|
<q-tab name="installed" :label="$t('installed')"></q-tab>
|
||||||
<q-tab name="all" :label="$t('all')"></q-tab>
|
<q-tab name="all" :label="$t('all')"></q-tab>
|
||||||
<q-tab name="featured" :label="$t('featured')"></q-tab>
|
<q-tab
|
||||||
|
v-show="$q.screen.gt.xs"
|
||||||
|
name="featured"
|
||||||
|
:label="$t('featured')"
|
||||||
|
></q-tab>
|
||||||
|
<q-btn-dropdown auto-close stretch flat :label="$t('categories')">
|
||||||
|
<q-list>
|
||||||
|
<q-item
|
||||||
|
clickable
|
||||||
|
v-close-popup
|
||||||
|
v-for="category in categories"
|
||||||
|
@click="tab = category"
|
||||||
|
:key="category"
|
||||||
|
>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label
|
||||||
|
class="text-capitalize"
|
||||||
|
v-text="category"
|
||||||
|
></q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</q-btn-dropdown>
|
||||||
<i
|
<i
|
||||||
v-if="!g.user.admin && tab != 'installed'"
|
v-if="!g.user.admin && tab != 'installed'"
|
||||||
v-text="$t('only_admins_can_install')"
|
v-text="$t('only_admins_can_install')"
|
||||||
|
|||||||
Reference in New Issue
Block a user