initial implementation of community packages

This commit is contained in:
Girish Ramakrishnan
2026-02-05 13:20:00 +01:00
parent a931d2a91f
commit a7de7fb286
11 changed files with 238 additions and 70 deletions
+18 -5
View File
@@ -13,6 +13,7 @@ import DomainsModel from '../models/DomainsModel.js';
import ApplinkDialog from '../components/ApplinkDialog.vue';
import AppInstallDialog from '../components/AppInstallDialog.vue';
import AppStoreItem from '../components/AppStoreItem.vue';
import CommunityAppDialog from '../components/CommunityAppDialog.vue';
const appsModel = AppsModel.create();
const appstoreModel = AppstoreModel.create();
@@ -143,16 +144,17 @@ async function onHashChange() {
const params = new URLSearchParams(window.location.hash.slice(window.location.hash.indexOf('?')));
const version = params.get('version') || 'latest';
try {
await appInstallDialog.value.open(appId, version, installedApps.value.length >= features.value.appMaxCount, domains.value);
// eslint-disable-next-line no-unused-vars
} catch (e) {
inputDialog.value.info({
const [error, appData] = await appstoreModel.get(appId, version);
if (error) {
console.error(error);
return inputDialog.value.info({
title: t('appstore.appNotFoundDialog.title'),
message: t('appstore.appNotFoundDialog.description', { appId, version }),
confirmLabel: t('main.dialog.close'),
});
}
appInstallDialog.value.open(appData, installedApps.value.length >= features.value.appMaxCount, domains.value);
}
}
@@ -178,6 +180,7 @@ async function getDomains() {
domains.value = result;
}
const applinkDialog = useTemplateRef('applinkDialog');
const communityAppDialog = useTemplateRef('communityAppDialog');
function onAddAppLink() {
applinkDialog.value.open();
@@ -187,6 +190,14 @@ function onApplinkAdded() {
window.location.href = '#/apps';
}
function onInstallCommunityApp() {
communityAppDialog.value.open();
}
function onCommunityAppSuccess(appData) {
appInstallDialog.value.open(appData, installedApps.value.length >= features.value.appMaxCount, domains.value);
}
onActivated(async () => {
setItemWidth();
@@ -222,6 +233,7 @@ onDeactivated(() => {
<div ref="view" class="content-large" style="width: 100%; height: 100%;">
<InputDialog ref="inputDialog"/>
<ApplinkDialog ref="applinkDialog" @success="onApplinkAdded"/>
<CommunityAppDialog ref="communityAppDialog" @success="onCommunityAppSuccess"/>
<AppInstallDialog ref="appInstallDialog" @close="onAppInstallDialogClose"/>
<div class="filter-bar">
@@ -229,6 +241,7 @@ onDeactivated(() => {
<TextInput ref="searchInput" @keydown.esc="search = ''" v-model="search" :disabled="!ready" :placeholder="$t('appstore.searchPlaceholder')" style="flex-grow: 1;" autocomplete="off"/>
<Button tool outline href="/#/appstore/io.cloudron.builtin.appproxy">Add app proxy</Button>
<Button tool outline @click="onAddAppLink()">Add external link</Button>
<Button tool outline @click="onInstallCommunityApp()">Install Community App</Button>
</div>
<div v-if="!ready" style="margin-top: 15px">