feat(update app): front end and queries
This commit is contained in:
parent
cb38cc9c90
commit
f484793a47
19 changed files with 668 additions and 322 deletions
|
@ -1,7 +1,8 @@
|
|||
import { Box, SlideFade, useColorModeValue } from '@chakra-ui/react';
|
||||
import { Box, SlideFade, Tag, useColorModeValue, Tooltip } from '@chakra-ui/react';
|
||||
import Link from 'next/link';
|
||||
import React from 'react';
|
||||
import { FiChevronRight } from 'react-icons/fi';
|
||||
import { MdSystemUpdateAlt } from 'react-icons/md';
|
||||
import AppStatus from './AppStatus';
|
||||
import AppLogo from '../AppLogo/AppLogo';
|
||||
import { limitText } from '../../modules/AppStore/helpers/table.helpers';
|
||||
|
@ -9,7 +10,7 @@ import { AppInfo, AppStatusEnum } from '../../generated/graphql';
|
|||
|
||||
type AppTileInfo = Pick<AppInfo, 'id' | 'name' | 'description' | 'short_desc'>;
|
||||
|
||||
const AppTile: React.FC<{ app: AppTileInfo; status: AppStatusEnum }> = ({ app, status }) => {
|
||||
const AppTile: React.FC<{ app: AppTileInfo; status: AppStatusEnum; updateAvailable: boolean }> = ({ app, status, updateAvailable }) => {
|
||||
const bg = useColorModeValue('white', '#1a202c');
|
||||
|
||||
return (
|
||||
|
@ -18,7 +19,16 @@ const AppTile: React.FC<{ app: AppTileInfo; status: AppStatusEnum }> = ({ app, s
|
|||
<Box bg={bg} className="flex flex-1 border-2 drop-shadow-sm rounded-lg p-3 items-center cursor-pointer group hover:drop-shadow-md transition-all">
|
||||
<AppLogo alt={`${app.name} logo`} className="mr-3 group-hover:scale-105 transition-all" id={app.id} size={100} />
|
||||
<div className="mr-3 flex-1">
|
||||
<h3 className="font-bold text-xl">{app.name}</h3>
|
||||
<div className="flex">
|
||||
<h3 className="font-bold text-xl mr-2">{app.name}</h3>
|
||||
{updateAvailable && (
|
||||
<Tooltip label="Update available">
|
||||
<Tag colorScheme="gray">
|
||||
<MdSystemUpdateAlt size={15} />
|
||||
</Tag>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
<span>{limitText(app.short_desc, 50)}</span>
|
||||
<div className="flex mt-1">
|
||||
<AppStatus status={status} />
|
||||
|
|
|
@ -24,12 +24,13 @@ export type App = {
|
|||
config: Scalars['JSONObject'];
|
||||
createdAt: Scalars['DateTime'];
|
||||
id: Scalars['String'];
|
||||
info: AppInfo;
|
||||
info?: Maybe<AppInfo>;
|
||||
lastOpened: Scalars['DateTime'];
|
||||
numOpened: Scalars['Float'];
|
||||
status: AppStatusEnum;
|
||||
updateInfo?: Maybe<UpdateInfo>;
|
||||
updatedAt: Scalars['DateTime'];
|
||||
version: Scalars['Float'];
|
||||
version?: Maybe<Scalars['Float']>;
|
||||
};
|
||||
|
||||
export enum AppCategoriesEnum {
|
||||
|
@ -45,7 +46,7 @@ export enum AppCategoriesEnum {
|
|||
Photography = 'PHOTOGRAPHY',
|
||||
Security = 'SECURITY',
|
||||
Social = 'SOCIAL',
|
||||
Utilities = 'UTILITIES'
|
||||
Utilities = 'UTILITIES',
|
||||
}
|
||||
|
||||
export type AppInfo = {
|
||||
|
@ -78,7 +79,8 @@ export enum AppStatusEnum {
|
|||
Starting = 'STARTING',
|
||||
Stopped = 'STOPPED',
|
||||
Stopping = 'STOPPING',
|
||||
Uninstalling = 'UNINSTALLING'
|
||||
Uninstalling = 'UNINSTALLING',
|
||||
Updating = 'UPDATING',
|
||||
}
|
||||
|
||||
export type Cpu = {
|
||||
|
@ -102,7 +104,7 @@ export enum FieldTypesEnum {
|
|||
Password = 'password',
|
||||
Random = 'random',
|
||||
Text = 'text',
|
||||
Url = 'url'
|
||||
Url = 'url',
|
||||
}
|
||||
|
||||
export type FormField = {
|
||||
|
@ -131,39 +133,37 @@ export type Mutation = {
|
|||
startApp: App;
|
||||
stopApp: App;
|
||||
uninstallApp: App;
|
||||
updateApp: App;
|
||||
updateAppConfig: App;
|
||||
};
|
||||
|
||||
|
||||
export type MutationInstallAppArgs = {
|
||||
input: AppInputType;
|
||||
};
|
||||
|
||||
|
||||
export type MutationLoginArgs = {
|
||||
input: UsernamePasswordInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationRegisterArgs = {
|
||||
input: UsernamePasswordInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationStartAppArgs = {
|
||||
id: Scalars['String'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationStopAppArgs = {
|
||||
id: Scalars['String'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationUninstallAppArgs = {
|
||||
id: Scalars['String'];
|
||||
};
|
||||
|
||||
export type MutationUpdateAppArgs = {
|
||||
id: Scalars['String'];
|
||||
};
|
||||
|
||||
export type MutationUpdateAppConfigArgs = {
|
||||
input: AppInputType;
|
||||
|
@ -180,7 +180,6 @@ export type Query = {
|
|||
version: VersionResponse;
|
||||
};
|
||||
|
||||
|
||||
export type QueryGetAppArgs = {
|
||||
id: Scalars['String'];
|
||||
};
|
||||
|
@ -192,6 +191,12 @@ export type SystemInfoResponse = {
|
|||
memory: DiskMemory;
|
||||
};
|
||||
|
||||
export type UpdateInfo = {
|
||||
__typename?: 'UpdateInfo';
|
||||
current: Scalars['Float'];
|
||||
latest: Scalars['Float'];
|
||||
};
|
||||
|
||||
export type User = {
|
||||
__typename?: 'User';
|
||||
createdAt: Scalars['DateTime'];
|
||||
|
@ -220,103 +225,165 @@ export type InstallAppMutationVariables = Exact<{
|
|||
input: AppInputType;
|
||||
}>;
|
||||
|
||||
|
||||
export type InstallAppMutation = { __typename?: 'Mutation', installApp: { __typename: 'App', id: string, status: AppStatusEnum } };
|
||||
export type InstallAppMutation = { __typename?: 'Mutation'; installApp: { __typename: 'App'; id: string; status: AppStatusEnum } };
|
||||
|
||||
export type LoginMutationVariables = Exact<{
|
||||
input: UsernamePasswordInput;
|
||||
}>;
|
||||
|
||||
export type LoginMutation = { __typename?: 'Mutation'; login: { __typename?: 'UserResponse'; user?: { __typename?: 'User'; id: string } | null } };
|
||||
|
||||
export type LoginMutation = { __typename?: 'Mutation', login: { __typename?: 'UserResponse', user?: { __typename?: 'User', id: string } | null } };
|
||||
export type LogoutMutationVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type LogoutMutationVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type LogoutMutation = { __typename?: 'Mutation', logout: boolean };
|
||||
export type LogoutMutation = { __typename?: 'Mutation'; logout: boolean };
|
||||
|
||||
export type RegisterMutationVariables = Exact<{
|
||||
input: UsernamePasswordInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type RegisterMutation = { __typename?: 'Mutation', register: { __typename?: 'UserResponse', user?: { __typename?: 'User', id: string } | null } };
|
||||
export type RegisterMutation = { __typename?: 'Mutation'; register: { __typename?: 'UserResponse'; user?: { __typename?: 'User'; id: string } | null } };
|
||||
|
||||
export type StartAppMutationVariables = Exact<{
|
||||
id: Scalars['String'];
|
||||
}>;
|
||||
|
||||
|
||||
export type StartAppMutation = { __typename?: 'Mutation', startApp: { __typename: 'App', id: string, status: AppStatusEnum } };
|
||||
export type StartAppMutation = { __typename?: 'Mutation'; startApp: { __typename: 'App'; id: string; status: AppStatusEnum } };
|
||||
|
||||
export type StopAppMutationVariables = Exact<{
|
||||
id: Scalars['String'];
|
||||
}>;
|
||||
|
||||
|
||||
export type StopAppMutation = { __typename?: 'Mutation', stopApp: { __typename: 'App', id: string, status: AppStatusEnum } };
|
||||
export type StopAppMutation = { __typename?: 'Mutation'; stopApp: { __typename: 'App'; id: string; status: AppStatusEnum } };
|
||||
|
||||
export type UninstallAppMutationVariables = Exact<{
|
||||
id: Scalars['String'];
|
||||
}>;
|
||||
|
||||
export type UninstallAppMutation = { __typename?: 'Mutation'; uninstallApp: { __typename: 'App'; id: string; status: AppStatusEnum } };
|
||||
|
||||
export type UninstallAppMutation = { __typename?: 'Mutation', uninstallApp: { __typename: 'App', id: string, status: AppStatusEnum } };
|
||||
export type UpdateAppMutationVariables = Exact<{
|
||||
id: Scalars['String'];
|
||||
}>;
|
||||
|
||||
export type UpdateAppMutation = { __typename?: 'Mutation'; updateApp: { __typename: 'App'; id: string; status: AppStatusEnum } };
|
||||
|
||||
export type UpdateAppConfigMutationVariables = Exact<{
|
||||
input: AppInputType;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateAppConfigMutation = { __typename?: 'Mutation', updateAppConfig: { __typename: 'App', id: string, status: AppStatusEnum } };
|
||||
export type UpdateAppConfigMutation = { __typename?: 'Mutation'; updateAppConfig: { __typename: 'App'; id: string; status: AppStatusEnum } };
|
||||
|
||||
export type GetAppQueryVariables = Exact<{
|
||||
appId: Scalars['String'];
|
||||
}>;
|
||||
|
||||
export type GetAppQuery = {
|
||||
__typename?: 'Query';
|
||||
getApp: {
|
||||
__typename?: 'App';
|
||||
id: string;
|
||||
status: AppStatusEnum;
|
||||
config: any;
|
||||
version?: number | null;
|
||||
updateInfo?: { __typename?: 'UpdateInfo'; current: number; latest: number } | null;
|
||||
info?: {
|
||||
__typename?: 'AppInfo';
|
||||
id: string;
|
||||
port: number;
|
||||
name: string;
|
||||
description: string;
|
||||
available: boolean;
|
||||
version?: string | null;
|
||||
tipi_version: number;
|
||||
short_desc: string;
|
||||
author: string;
|
||||
source: string;
|
||||
categories: Array<AppCategoriesEnum>;
|
||||
url_suffix?: string | null;
|
||||
form_fields: Array<{
|
||||
__typename?: 'FormField';
|
||||
type: FieldTypesEnum;
|
||||
label: string;
|
||||
max?: number | null;
|
||||
min?: number | null;
|
||||
hint?: string | null;
|
||||
required?: boolean | null;
|
||||
env_variable: string;
|
||||
}>;
|
||||
} | null;
|
||||
};
|
||||
};
|
||||
|
||||
export type GetAppQuery = { __typename?: 'Query', getApp: { __typename?: 'App', id: string, status: AppStatusEnum, config: any, version: number, info: { __typename?: 'AppInfo', id: string, port: number, name: string, description: string, available: boolean, version?: string | null, tipi_version: number, short_desc: string, author: string, source: string, categories: Array<AppCategoriesEnum>, url_suffix?: string | null, form_fields: Array<{ __typename?: 'FormField', type: FieldTypesEnum, label: string, max?: number | null, min?: number | null, hint?: string | null, required?: boolean | null, env_variable: string }> } } };
|
||||
export type InstalledAppsQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type InstalledAppsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
export type InstalledAppsQuery = {
|
||||
__typename?: 'Query';
|
||||
installedApps: Array<{
|
||||
__typename?: 'App';
|
||||
id: string;
|
||||
status: AppStatusEnum;
|
||||
config: any;
|
||||
version?: number | null;
|
||||
updateInfo?: { __typename?: 'UpdateInfo'; current: number; latest: number } | null;
|
||||
info?: { __typename?: 'AppInfo'; id: string; name: string; description: string; tipi_version: number; short_desc: string } | null;
|
||||
}>;
|
||||
};
|
||||
|
||||
export type ConfiguredQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type InstalledAppsQuery = { __typename?: 'Query', installedApps: Array<{ __typename?: 'App', id: string, status: AppStatusEnum, config: any, version: number, info: { __typename?: 'AppInfo', id: string, name: string, description: string, tipi_version: number, short_desc: string } }> };
|
||||
export type ConfiguredQuery = { __typename?: 'Query'; isConfigured: boolean };
|
||||
|
||||
export type ConfiguredQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
export type ListAppsQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type ListAppsQuery = {
|
||||
__typename?: 'Query';
|
||||
listAppsInfo: {
|
||||
__typename?: 'ListAppsResonse';
|
||||
total: number;
|
||||
apps: Array<{
|
||||
__typename?: 'AppInfo';
|
||||
id: string;
|
||||
available: boolean;
|
||||
tipi_version: number;
|
||||
port: number;
|
||||
name: string;
|
||||
version?: string | null;
|
||||
short_desc: string;
|
||||
author: string;
|
||||
categories: Array<AppCategoriesEnum>;
|
||||
}>;
|
||||
};
|
||||
};
|
||||
|
||||
export type ConfiguredQuery = { __typename?: 'Query', isConfigured: boolean };
|
||||
export type MeQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type ListAppsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
export type MeQuery = { __typename?: 'Query'; me?: { __typename?: 'User'; id: string } | null };
|
||||
|
||||
export type SystemInfoQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type ListAppsQuery = { __typename?: 'Query', listAppsInfo: { __typename?: 'ListAppsResonse', total: number, apps: Array<{ __typename?: 'AppInfo', id: string, available: boolean, tipi_version: number, port: number, name: string, version?: string | null, short_desc: string, author: string, categories: Array<AppCategoriesEnum> }> } };
|
||||
export type SystemInfoQuery = {
|
||||
__typename?: 'Query';
|
||||
systemInfo?: {
|
||||
__typename?: 'SystemInfoResponse';
|
||||
cpu: { __typename?: 'Cpu'; load: number };
|
||||
disk: { __typename?: 'DiskMemory'; available: number; used: number; total: number };
|
||||
memory: { __typename?: 'DiskMemory'; available: number; used: number; total: number };
|
||||
} | null;
|
||||
};
|
||||
|
||||
export type MeQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type MeQuery = { __typename?: 'Query', me?: { __typename?: 'User', id: string } | null };
|
||||
|
||||
export type SystemInfoQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type SystemInfoQuery = { __typename?: 'Query', systemInfo?: { __typename?: 'SystemInfoResponse', cpu: { __typename?: 'Cpu', load: number }, disk: { __typename?: 'DiskMemory', available: number, used: number, total: number }, memory: { __typename?: 'DiskMemory', available: number, used: number, total: number } } | null };
|
||||
|
||||
export type VersionQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type VersionQuery = { __typename?: 'Query', version: { __typename?: 'VersionResponse', current: string, latest?: string | null } };
|
||||
export type VersionQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type VersionQuery = { __typename?: 'Query'; version: { __typename?: 'VersionResponse'; current: string; latest?: string | null } };
|
||||
|
||||
export const InstallAppDocument = gql`
|
||||
mutation InstallApp($input: AppInputType!) {
|
||||
installApp(input: $input) {
|
||||
id
|
||||
status
|
||||
__typename
|
||||
mutation InstallApp($input: AppInputType!) {
|
||||
installApp(input: $input) {
|
||||
id
|
||||
status
|
||||
__typename
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
`;
|
||||
export type InstallAppMutationFn = Apollo.MutationFunction<InstallAppMutation, InstallAppMutationVariables>;
|
||||
|
||||
/**
|
||||
|
@ -337,21 +404,21 @@ export type InstallAppMutationFn = Apollo.MutationFunction<InstallAppMutation, I
|
|||
* });
|
||||
*/
|
||||
export function useInstallAppMutation(baseOptions?: Apollo.MutationHookOptions<InstallAppMutation, InstallAppMutationVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useMutation<InstallAppMutation, InstallAppMutationVariables>(InstallAppDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useMutation<InstallAppMutation, InstallAppMutationVariables>(InstallAppDocument, options);
|
||||
}
|
||||
export type InstallAppMutationHookResult = ReturnType<typeof useInstallAppMutation>;
|
||||
export type InstallAppMutationResult = Apollo.MutationResult<InstallAppMutation>;
|
||||
export type InstallAppMutationOptions = Apollo.BaseMutationOptions<InstallAppMutation, InstallAppMutationVariables>;
|
||||
export const LoginDocument = gql`
|
||||
mutation Login($input: UsernamePasswordInput!) {
|
||||
login(input: $input) {
|
||||
user {
|
||||
id
|
||||
mutation Login($input: UsernamePasswordInput!) {
|
||||
login(input: $input) {
|
||||
user {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
`;
|
||||
export type LoginMutationFn = Apollo.MutationFunction<LoginMutation, LoginMutationVariables>;
|
||||
|
||||
/**
|
||||
|
@ -372,17 +439,17 @@ export type LoginMutationFn = Apollo.MutationFunction<LoginMutation, LoginMutati
|
|||
* });
|
||||
*/
|
||||
export function useLoginMutation(baseOptions?: Apollo.MutationHookOptions<LoginMutation, LoginMutationVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useMutation<LoginMutation, LoginMutationVariables>(LoginDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useMutation<LoginMutation, LoginMutationVariables>(LoginDocument, options);
|
||||
}
|
||||
export type LoginMutationHookResult = ReturnType<typeof useLoginMutation>;
|
||||
export type LoginMutationResult = Apollo.MutationResult<LoginMutation>;
|
||||
export type LoginMutationOptions = Apollo.BaseMutationOptions<LoginMutation, LoginMutationVariables>;
|
||||
export const LogoutDocument = gql`
|
||||
mutation Logout {
|
||||
logout
|
||||
}
|
||||
`;
|
||||
mutation Logout {
|
||||
logout
|
||||
}
|
||||
`;
|
||||
export type LogoutMutationFn = Apollo.MutationFunction<LogoutMutation, LogoutMutationVariables>;
|
||||
|
||||
/**
|
||||
|
@ -402,21 +469,21 @@ export type LogoutMutationFn = Apollo.MutationFunction<LogoutMutation, LogoutMut
|
|||
* });
|
||||
*/
|
||||
export function useLogoutMutation(baseOptions?: Apollo.MutationHookOptions<LogoutMutation, LogoutMutationVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useMutation<LogoutMutation, LogoutMutationVariables>(LogoutDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useMutation<LogoutMutation, LogoutMutationVariables>(LogoutDocument, options);
|
||||
}
|
||||
export type LogoutMutationHookResult = ReturnType<typeof useLogoutMutation>;
|
||||
export type LogoutMutationResult = Apollo.MutationResult<LogoutMutation>;
|
||||
export type LogoutMutationOptions = Apollo.BaseMutationOptions<LogoutMutation, LogoutMutationVariables>;
|
||||
export const RegisterDocument = gql`
|
||||
mutation Register($input: UsernamePasswordInput!) {
|
||||
register(input: $input) {
|
||||
user {
|
||||
id
|
||||
mutation Register($input: UsernamePasswordInput!) {
|
||||
register(input: $input) {
|
||||
user {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
`;
|
||||
export type RegisterMutationFn = Apollo.MutationFunction<RegisterMutation, RegisterMutationVariables>;
|
||||
|
||||
/**
|
||||
|
@ -437,21 +504,21 @@ export type RegisterMutationFn = Apollo.MutationFunction<RegisterMutation, Regis
|
|||
* });
|
||||
*/
|
||||
export function useRegisterMutation(baseOptions?: Apollo.MutationHookOptions<RegisterMutation, RegisterMutationVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useMutation<RegisterMutation, RegisterMutationVariables>(RegisterDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useMutation<RegisterMutation, RegisterMutationVariables>(RegisterDocument, options);
|
||||
}
|
||||
export type RegisterMutationHookResult = ReturnType<typeof useRegisterMutation>;
|
||||
export type RegisterMutationResult = Apollo.MutationResult<RegisterMutation>;
|
||||
export type RegisterMutationOptions = Apollo.BaseMutationOptions<RegisterMutation, RegisterMutationVariables>;
|
||||
export const StartAppDocument = gql`
|
||||
mutation StartApp($id: String!) {
|
||||
startApp(id: $id) {
|
||||
id
|
||||
status
|
||||
__typename
|
||||
mutation StartApp($id: String!) {
|
||||
startApp(id: $id) {
|
||||
id
|
||||
status
|
||||
__typename
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
`;
|
||||
export type StartAppMutationFn = Apollo.MutationFunction<StartAppMutation, StartAppMutationVariables>;
|
||||
|
||||
/**
|
||||
|
@ -472,21 +539,21 @@ export type StartAppMutationFn = Apollo.MutationFunction<StartAppMutation, Start
|
|||
* });
|
||||
*/
|
||||
export function useStartAppMutation(baseOptions?: Apollo.MutationHookOptions<StartAppMutation, StartAppMutationVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useMutation<StartAppMutation, StartAppMutationVariables>(StartAppDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useMutation<StartAppMutation, StartAppMutationVariables>(StartAppDocument, options);
|
||||
}
|
||||
export type StartAppMutationHookResult = ReturnType<typeof useStartAppMutation>;
|
||||
export type StartAppMutationResult = Apollo.MutationResult<StartAppMutation>;
|
||||
export type StartAppMutationOptions = Apollo.BaseMutationOptions<StartAppMutation, StartAppMutationVariables>;
|
||||
export const StopAppDocument = gql`
|
||||
mutation StopApp($id: String!) {
|
||||
stopApp(id: $id) {
|
||||
id
|
||||
status
|
||||
__typename
|
||||
mutation StopApp($id: String!) {
|
||||
stopApp(id: $id) {
|
||||
id
|
||||
status
|
||||
__typename
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
`;
|
||||
export type StopAppMutationFn = Apollo.MutationFunction<StopAppMutation, StopAppMutationVariables>;
|
||||
|
||||
/**
|
||||
|
@ -507,21 +574,21 @@ export type StopAppMutationFn = Apollo.MutationFunction<StopAppMutation, StopApp
|
|||
* });
|
||||
*/
|
||||
export function useStopAppMutation(baseOptions?: Apollo.MutationHookOptions<StopAppMutation, StopAppMutationVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useMutation<StopAppMutation, StopAppMutationVariables>(StopAppDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useMutation<StopAppMutation, StopAppMutationVariables>(StopAppDocument, options);
|
||||
}
|
||||
export type StopAppMutationHookResult = ReturnType<typeof useStopAppMutation>;
|
||||
export type StopAppMutationResult = Apollo.MutationResult<StopAppMutation>;
|
||||
export type StopAppMutationOptions = Apollo.BaseMutationOptions<StopAppMutation, StopAppMutationVariables>;
|
||||
export const UninstallAppDocument = gql`
|
||||
mutation UninstallApp($id: String!) {
|
||||
uninstallApp(id: $id) {
|
||||
id
|
||||
status
|
||||
__typename
|
||||
mutation UninstallApp($id: String!) {
|
||||
uninstallApp(id: $id) {
|
||||
id
|
||||
status
|
||||
__typename
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
`;
|
||||
export type UninstallAppMutationFn = Apollo.MutationFunction<UninstallAppMutation, UninstallAppMutationVariables>;
|
||||
|
||||
/**
|
||||
|
@ -542,21 +609,56 @@ export type UninstallAppMutationFn = Apollo.MutationFunction<UninstallAppMutatio
|
|||
* });
|
||||
*/
|
||||
export function useUninstallAppMutation(baseOptions?: Apollo.MutationHookOptions<UninstallAppMutation, UninstallAppMutationVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useMutation<UninstallAppMutation, UninstallAppMutationVariables>(UninstallAppDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useMutation<UninstallAppMutation, UninstallAppMutationVariables>(UninstallAppDocument, options);
|
||||
}
|
||||
export type UninstallAppMutationHookResult = ReturnType<typeof useUninstallAppMutation>;
|
||||
export type UninstallAppMutationResult = Apollo.MutationResult<UninstallAppMutation>;
|
||||
export type UninstallAppMutationOptions = Apollo.BaseMutationOptions<UninstallAppMutation, UninstallAppMutationVariables>;
|
||||
export const UpdateAppConfigDocument = gql`
|
||||
mutation UpdateAppConfig($input: AppInputType!) {
|
||||
updateAppConfig(input: $input) {
|
||||
id
|
||||
status
|
||||
__typename
|
||||
export const UpdateAppDocument = gql`
|
||||
mutation UpdateApp($id: String!) {
|
||||
updateApp(id: $id) {
|
||||
id
|
||||
status
|
||||
__typename
|
||||
}
|
||||
}
|
||||
`;
|
||||
export type UpdateAppMutationFn = Apollo.MutationFunction<UpdateAppMutation, UpdateAppMutationVariables>;
|
||||
|
||||
/**
|
||||
* __useUpdateAppMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useUpdateAppMutation` within a React component and pass it any options that fit your needs.
|
||||
* When your component renders, `useUpdateAppMutation` returns a tuple that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - An object with fields that represent the current status of the mutation's execution
|
||||
*
|
||||
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||
*
|
||||
* @example
|
||||
* const [updateAppMutation, { data, loading, error }] = useUpdateAppMutation({
|
||||
* variables: {
|
||||
* id: // value for 'id'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useUpdateAppMutation(baseOptions?: Apollo.MutationHookOptions<UpdateAppMutation, UpdateAppMutationVariables>) {
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useMutation<UpdateAppMutation, UpdateAppMutationVariables>(UpdateAppDocument, options);
|
||||
}
|
||||
`;
|
||||
export type UpdateAppMutationHookResult = ReturnType<typeof useUpdateAppMutation>;
|
||||
export type UpdateAppMutationResult = Apollo.MutationResult<UpdateAppMutation>;
|
||||
export type UpdateAppMutationOptions = Apollo.BaseMutationOptions<UpdateAppMutation, UpdateAppMutationVariables>;
|
||||
export const UpdateAppConfigDocument = gql`
|
||||
mutation UpdateAppConfig($input: AppInputType!) {
|
||||
updateAppConfig(input: $input) {
|
||||
id
|
||||
status
|
||||
__typename
|
||||
}
|
||||
}
|
||||
`;
|
||||
export type UpdateAppConfigMutationFn = Apollo.MutationFunction<UpdateAppConfigMutation, UpdateAppConfigMutationVariables>;
|
||||
|
||||
/**
|
||||
|
@ -577,45 +679,49 @@ export type UpdateAppConfigMutationFn = Apollo.MutationFunction<UpdateAppConfigM
|
|||
* });
|
||||
*/
|
||||
export function useUpdateAppConfigMutation(baseOptions?: Apollo.MutationHookOptions<UpdateAppConfigMutation, UpdateAppConfigMutationVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useMutation<UpdateAppConfigMutation, UpdateAppConfigMutationVariables>(UpdateAppConfigDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useMutation<UpdateAppConfigMutation, UpdateAppConfigMutationVariables>(UpdateAppConfigDocument, options);
|
||||
}
|
||||
export type UpdateAppConfigMutationHookResult = ReturnType<typeof useUpdateAppConfigMutation>;
|
||||
export type UpdateAppConfigMutationResult = Apollo.MutationResult<UpdateAppConfigMutation>;
|
||||
export type UpdateAppConfigMutationOptions = Apollo.BaseMutationOptions<UpdateAppConfigMutation, UpdateAppConfigMutationVariables>;
|
||||
export const GetAppDocument = gql`
|
||||
query GetApp($appId: String!) {
|
||||
getApp(id: $appId) {
|
||||
id
|
||||
status
|
||||
config
|
||||
version
|
||||
info {
|
||||
query GetApp($appId: String!) {
|
||||
getApp(id: $appId) {
|
||||
id
|
||||
port
|
||||
name
|
||||
description
|
||||
available
|
||||
status
|
||||
config
|
||||
version
|
||||
tipi_version
|
||||
short_desc
|
||||
author
|
||||
source
|
||||
categories
|
||||
url_suffix
|
||||
form_fields {
|
||||
type
|
||||
label
|
||||
max
|
||||
min
|
||||
hint
|
||||
required
|
||||
env_variable
|
||||
updateInfo {
|
||||
current
|
||||
latest
|
||||
}
|
||||
info {
|
||||
id
|
||||
port
|
||||
name
|
||||
description
|
||||
available
|
||||
version
|
||||
tipi_version
|
||||
short_desc
|
||||
author
|
||||
source
|
||||
categories
|
||||
url_suffix
|
||||
form_fields {
|
||||
type
|
||||
label
|
||||
max
|
||||
min
|
||||
hint
|
||||
required
|
||||
env_variable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useGetAppQuery__
|
||||
|
@ -634,33 +740,37 @@ export const GetAppDocument = gql`
|
|||
* });
|
||||
*/
|
||||
export function useGetAppQuery(baseOptions: Apollo.QueryHookOptions<GetAppQuery, GetAppQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<GetAppQuery, GetAppQueryVariables>(GetAppDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useQuery<GetAppQuery, GetAppQueryVariables>(GetAppDocument, options);
|
||||
}
|
||||
export function useGetAppLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetAppQuery, GetAppQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<GetAppQuery, GetAppQueryVariables>(GetAppDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useLazyQuery<GetAppQuery, GetAppQueryVariables>(GetAppDocument, options);
|
||||
}
|
||||
export type GetAppQueryHookResult = ReturnType<typeof useGetAppQuery>;
|
||||
export type GetAppLazyQueryHookResult = ReturnType<typeof useGetAppLazyQuery>;
|
||||
export type GetAppQueryResult = Apollo.QueryResult<GetAppQuery, GetAppQueryVariables>;
|
||||
export const InstalledAppsDocument = gql`
|
||||
query InstalledApps {
|
||||
installedApps {
|
||||
id
|
||||
status
|
||||
config
|
||||
version
|
||||
info {
|
||||
query InstalledApps {
|
||||
installedApps {
|
||||
id
|
||||
name
|
||||
description
|
||||
tipi_version
|
||||
short_desc
|
||||
status
|
||||
config
|
||||
version
|
||||
updateInfo {
|
||||
current
|
||||
latest
|
||||
}
|
||||
info {
|
||||
id
|
||||
name
|
||||
description
|
||||
tipi_version
|
||||
short_desc
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useInstalledAppsQuery__
|
||||
|
@ -678,21 +788,21 @@ export const InstalledAppsDocument = gql`
|
|||
* });
|
||||
*/
|
||||
export function useInstalledAppsQuery(baseOptions?: Apollo.QueryHookOptions<InstalledAppsQuery, InstalledAppsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<InstalledAppsQuery, InstalledAppsQueryVariables>(InstalledAppsDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useQuery<InstalledAppsQuery, InstalledAppsQueryVariables>(InstalledAppsDocument, options);
|
||||
}
|
||||
export function useInstalledAppsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<InstalledAppsQuery, InstalledAppsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<InstalledAppsQuery, InstalledAppsQueryVariables>(InstalledAppsDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useLazyQuery<InstalledAppsQuery, InstalledAppsQueryVariables>(InstalledAppsDocument, options);
|
||||
}
|
||||
export type InstalledAppsQueryHookResult = ReturnType<typeof useInstalledAppsQuery>;
|
||||
export type InstalledAppsLazyQueryHookResult = ReturnType<typeof useInstalledAppsLazyQuery>;
|
||||
export type InstalledAppsQueryResult = Apollo.QueryResult<InstalledAppsQuery, InstalledAppsQueryVariables>;
|
||||
export const ConfiguredDocument = gql`
|
||||
query Configured {
|
||||
isConfigured
|
||||
}
|
||||
`;
|
||||
query Configured {
|
||||
isConfigured
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useConfiguredQuery__
|
||||
|
@ -710,34 +820,34 @@ export const ConfiguredDocument = gql`
|
|||
* });
|
||||
*/
|
||||
export function useConfiguredQuery(baseOptions?: Apollo.QueryHookOptions<ConfiguredQuery, ConfiguredQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<ConfiguredQuery, ConfiguredQueryVariables>(ConfiguredDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useQuery<ConfiguredQuery, ConfiguredQueryVariables>(ConfiguredDocument, options);
|
||||
}
|
||||
export function useConfiguredLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ConfiguredQuery, ConfiguredQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<ConfiguredQuery, ConfiguredQueryVariables>(ConfiguredDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useLazyQuery<ConfiguredQuery, ConfiguredQueryVariables>(ConfiguredDocument, options);
|
||||
}
|
||||
export type ConfiguredQueryHookResult = ReturnType<typeof useConfiguredQuery>;
|
||||
export type ConfiguredLazyQueryHookResult = ReturnType<typeof useConfiguredLazyQuery>;
|
||||
export type ConfiguredQueryResult = Apollo.QueryResult<ConfiguredQuery, ConfiguredQueryVariables>;
|
||||
export const ListAppsDocument = gql`
|
||||
query ListApps {
|
||||
listAppsInfo {
|
||||
apps {
|
||||
id
|
||||
available
|
||||
tipi_version
|
||||
port
|
||||
name
|
||||
version
|
||||
short_desc
|
||||
author
|
||||
categories
|
||||
query ListApps {
|
||||
listAppsInfo {
|
||||
apps {
|
||||
id
|
||||
available
|
||||
tipi_version
|
||||
port
|
||||
name
|
||||
version
|
||||
short_desc
|
||||
author
|
||||
categories
|
||||
}
|
||||
total
|
||||
}
|
||||
total
|
||||
}
|
||||
}
|
||||
`;
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useListAppsQuery__
|
||||
|
@ -755,23 +865,23 @@ export const ListAppsDocument = gql`
|
|||
* });
|
||||
*/
|
||||
export function useListAppsQuery(baseOptions?: Apollo.QueryHookOptions<ListAppsQuery, ListAppsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<ListAppsQuery, ListAppsQueryVariables>(ListAppsDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useQuery<ListAppsQuery, ListAppsQueryVariables>(ListAppsDocument, options);
|
||||
}
|
||||
export function useListAppsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ListAppsQuery, ListAppsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<ListAppsQuery, ListAppsQueryVariables>(ListAppsDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useLazyQuery<ListAppsQuery, ListAppsQueryVariables>(ListAppsDocument, options);
|
||||
}
|
||||
export type ListAppsQueryHookResult = ReturnType<typeof useListAppsQuery>;
|
||||
export type ListAppsLazyQueryHookResult = ReturnType<typeof useListAppsLazyQuery>;
|
||||
export type ListAppsQueryResult = Apollo.QueryResult<ListAppsQuery, ListAppsQueryVariables>;
|
||||
export const MeDocument = gql`
|
||||
query Me {
|
||||
me {
|
||||
id
|
||||
query Me {
|
||||
me {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useMeQuery__
|
||||
|
@ -789,35 +899,35 @@ export const MeDocument = gql`
|
|||
* });
|
||||
*/
|
||||
export function useMeQuery(baseOptions?: Apollo.QueryHookOptions<MeQuery, MeQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<MeQuery, MeQueryVariables>(MeDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useQuery<MeQuery, MeQueryVariables>(MeDocument, options);
|
||||
}
|
||||
export function useMeLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MeQuery, MeQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<MeQuery, MeQueryVariables>(MeDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useLazyQuery<MeQuery, MeQueryVariables>(MeDocument, options);
|
||||
}
|
||||
export type MeQueryHookResult = ReturnType<typeof useMeQuery>;
|
||||
export type MeLazyQueryHookResult = ReturnType<typeof useMeLazyQuery>;
|
||||
export type MeQueryResult = Apollo.QueryResult<MeQuery, MeQueryVariables>;
|
||||
export const SystemInfoDocument = gql`
|
||||
query SystemInfo {
|
||||
systemInfo {
|
||||
cpu {
|
||||
load
|
||||
}
|
||||
disk {
|
||||
available
|
||||
used
|
||||
total
|
||||
}
|
||||
memory {
|
||||
available
|
||||
used
|
||||
total
|
||||
query SystemInfo {
|
||||
systemInfo {
|
||||
cpu {
|
||||
load
|
||||
}
|
||||
disk {
|
||||
available
|
||||
used
|
||||
total
|
||||
}
|
||||
memory {
|
||||
available
|
||||
used
|
||||
total
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useSystemInfoQuery__
|
||||
|
@ -835,24 +945,24 @@ export const SystemInfoDocument = gql`
|
|||
* });
|
||||
*/
|
||||
export function useSystemInfoQuery(baseOptions?: Apollo.QueryHookOptions<SystemInfoQuery, SystemInfoQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<SystemInfoQuery, SystemInfoQueryVariables>(SystemInfoDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useQuery<SystemInfoQuery, SystemInfoQueryVariables>(SystemInfoDocument, options);
|
||||
}
|
||||
export function useSystemInfoLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<SystemInfoQuery, SystemInfoQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<SystemInfoQuery, SystemInfoQueryVariables>(SystemInfoDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useLazyQuery<SystemInfoQuery, SystemInfoQueryVariables>(SystemInfoDocument, options);
|
||||
}
|
||||
export type SystemInfoQueryHookResult = ReturnType<typeof useSystemInfoQuery>;
|
||||
export type SystemInfoLazyQueryHookResult = ReturnType<typeof useSystemInfoLazyQuery>;
|
||||
export type SystemInfoQueryResult = Apollo.QueryResult<SystemInfoQuery, SystemInfoQueryVariables>;
|
||||
export const VersionDocument = gql`
|
||||
query Version {
|
||||
version {
|
||||
current
|
||||
latest
|
||||
query Version {
|
||||
version {
|
||||
current
|
||||
latest
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useVersionQuery__
|
||||
|
@ -870,13 +980,13 @@ export const VersionDocument = gql`
|
|||
* });
|
||||
*/
|
||||
export function useVersionQuery(baseOptions?: Apollo.QueryHookOptions<VersionQuery, VersionQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<VersionQuery, VersionQueryVariables>(VersionDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useQuery<VersionQuery, VersionQueryVariables>(VersionDocument, options);
|
||||
}
|
||||
export function useVersionLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<VersionQuery, VersionQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<VersionQuery, VersionQueryVariables>(VersionDocument, options);
|
||||
}
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
return Apollo.useLazyQuery<VersionQuery, VersionQueryVariables>(VersionDocument, options);
|
||||
}
|
||||
export type VersionQueryHookResult = ReturnType<typeof useVersionQuery>;
|
||||
export type VersionLazyQueryHookResult = ReturnType<typeof useVersionLazyQuery>;
|
||||
export type VersionQueryResult = Apollo.QueryResult<VersionQuery, VersionQueryVariables>;
|
||||
export type VersionQueryResult = Apollo.QueryResult<VersionQuery, VersionQueryVariables>;
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
mutation UpdateApp($id: String!) {
|
||||
updateApp(id: $id) {
|
||||
id
|
||||
status
|
||||
__typename
|
||||
}
|
||||
}
|
|
@ -4,6 +4,10 @@ query GetApp($appId: String!) {
|
|||
status
|
||||
config
|
||||
version
|
||||
updateInfo {
|
||||
current
|
||||
latest
|
||||
}
|
||||
info {
|
||||
id
|
||||
port
|
||||
|
|
|
@ -4,6 +4,10 @@ query InstalledApps {
|
|||
status
|
||||
config
|
||||
version
|
||||
updateInfo {
|
||||
current
|
||||
latest
|
||||
}
|
||||
info {
|
||||
id
|
||||
name
|
||||
|
|
|
@ -1,78 +1,141 @@
|
|||
import { Button } from '@chakra-ui/react';
|
||||
import { Button, Tooltip } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
import { FiExternalLink, FiPause, FiPlay, FiSettings, FiTrash2 } from 'react-icons/fi';
|
||||
import { MdSystemUpdateAlt } from 'react-icons/md';
|
||||
import { TiCancel } from 'react-icons/ti';
|
||||
import { AppInfo, AppStatusEnum } from '../../../generated/graphql';
|
||||
|
||||
interface IProps {
|
||||
app: AppInfo;
|
||||
status?: AppStatusEnum;
|
||||
updateAvailable: boolean;
|
||||
onInstall: () => void;
|
||||
onUninstall: () => void;
|
||||
onStart: () => void;
|
||||
onStop: () => void;
|
||||
onOpen: () => void;
|
||||
onUpdate: () => void;
|
||||
onUpdateSettings: () => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
const AppActions: React.FC<IProps> = ({ app, status, onInstall, onUninstall, onStart, onStop, onOpen, onUpdate, onCancel }) => {
|
||||
const AppActions: React.FC<IProps> = ({ app, status, onInstall, onUninstall, onStart, onStop, onOpen, onUpdate, onCancel, updateAvailable, onUpdateSettings }) => {
|
||||
const hasSettings = Object.keys(app.form_fields).length > 0;
|
||||
|
||||
if (status === AppStatusEnum.Stopped) {
|
||||
return (
|
||||
<div className="flex flex-wrap justify-center">
|
||||
const buttons: JSX.Element[] = [];
|
||||
|
||||
const renderStatus = () => {
|
||||
if (status === AppStatusEnum.Installing || status === AppStatusEnum.Uninstalling || status === AppStatusEnum.Starting || status === AppStatusEnum.Stopping || status === AppStatusEnum.Updating) {
|
||||
return <span className="text-gray-500 text-sm ml-2 mt-3 self-center text-center sm:text-left">{`App is ${status.toLowerCase()} please wait...`}</span>;
|
||||
}
|
||||
};
|
||||
|
||||
switch (status) {
|
||||
case AppStatusEnum.Stopped:
|
||||
buttons.push(
|
||||
<Button onClick={onStart} width={150} colorScheme="green" className="mt-3 mr-2">
|
||||
Start
|
||||
<FiPlay className="ml-1" />
|
||||
</Button>
|
||||
</Button>,
|
||||
<Button onClick={onUninstall} width={150} colorScheme="gray" className="mt-3 mr-2">
|
||||
Remove
|
||||
<FiTrash2 className="ml-1" />
|
||||
</Button>
|
||||
{hasSettings && (
|
||||
<Button onClick={onUpdate} width={150} colorScheme="gray" className="mt-3 mr-2">
|
||||
Settings
|
||||
<FiSettings className="ml-1" />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
} else if (status === AppStatusEnum.Running) {
|
||||
return (
|
||||
<div>
|
||||
</Button>,
|
||||
);
|
||||
if (hasSettings) {
|
||||
buttons.push(
|
||||
<Tooltip label="Update settings">
|
||||
<Button onClick={onUpdateSettings} colorScheme="gray" className="mt-3 mr-2">
|
||||
<FiSettings className="ml-1" />
|
||||
</Button>
|
||||
</Tooltip>,
|
||||
);
|
||||
}
|
||||
if (updateAvailable) {
|
||||
buttons.push(
|
||||
<Tooltip label="Download update">
|
||||
<Button onClick={onUpdate} colorScheme="gray" className="mt-3 mr-2">
|
||||
<MdSystemUpdateAlt className="ml-1" />
|
||||
</Button>
|
||||
</Tooltip>,
|
||||
);
|
||||
}
|
||||
break;
|
||||
case AppStatusEnum.Running:
|
||||
buttons.push(
|
||||
<Button onClick={onStop} width={150} colorScheme="red" className="mt-3 mr-2">
|
||||
Stop
|
||||
<FiPause className="ml-1" />
|
||||
</Button>,
|
||||
<Button onClick={onOpen} width={150} colorScheme="gray" className="mt-3 mr-2">
|
||||
Open
|
||||
<FiExternalLink className="ml-1" />
|
||||
</Button>
|
||||
<Button onClick={onStop} width={150} colorScheme="red" className="mt-3">
|
||||
Stop
|
||||
<FiPause className="ml-2" />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
} else if (status === AppStatusEnum.Installing || status === AppStatusEnum.Uninstalling || status === AppStatusEnum.Starting || status === AppStatusEnum.Stopping) {
|
||||
return (
|
||||
<div className="flex items-center sm:items-start flex-col md:flex-row">
|
||||
</Button>,
|
||||
);
|
||||
if (hasSettings) {
|
||||
buttons.push(
|
||||
<Tooltip label="Update settings">
|
||||
<Button onClick={onUpdateSettings} colorScheme="gray" className="mt-3 mr-2">
|
||||
<FiSettings className="ml-1" />
|
||||
</Button>
|
||||
</Tooltip>,
|
||||
);
|
||||
}
|
||||
if (updateAvailable) {
|
||||
buttons.push(
|
||||
<Tooltip label="Download update">
|
||||
<Button onClick={onUpdate} colorScheme="gray" className="mt-3 mr-2">
|
||||
<MdSystemUpdateAlt className="ml-1" />
|
||||
</Button>
|
||||
</Tooltip>,
|
||||
);
|
||||
}
|
||||
break;
|
||||
case AppStatusEnum.Installing:
|
||||
case AppStatusEnum.Uninstalling:
|
||||
case AppStatusEnum.Starting:
|
||||
case AppStatusEnum.Stopping:
|
||||
buttons.push(
|
||||
<Button isLoading onClick={() => null} width={160} colorScheme="green" className="mt-3">
|
||||
Install
|
||||
<FiPlay className="ml-1" />
|
||||
</Button>
|
||||
</Button>,
|
||||
<Button onClick={onCancel} colorScheme="gray" className="mt-3 mr-2 ml-2">
|
||||
<TiCancel />
|
||||
</Button>
|
||||
<span className="text-gray-500 text-sm ml-2 mt-3 self-center text-center sm:text-left">{`App is ${status.toLowerCase()} please wait and don't refresh page...`}</span>
|
||||
</div>
|
||||
);
|
||||
} else if (status === AppStatusEnum.Missing) {
|
||||
return (
|
||||
<Button onClick={onInstall} width={160} colorScheme="green" className="mt-3">
|
||||
Install
|
||||
</Button>
|
||||
);
|
||||
</Button>,
|
||||
);
|
||||
break;
|
||||
|
||||
case AppStatusEnum.Updating:
|
||||
buttons.push(
|
||||
<Button isLoading onClick={() => null} width={160} colorScheme="green" className="mt-3">
|
||||
Updating
|
||||
<FiPlay className="ml-1" />
|
||||
</Button>,
|
||||
<Button onClick={onCancel} colorScheme="gray" className="mt-3 mr-2 ml-2">
|
||||
<TiCancel />
|
||||
</Button>,
|
||||
);
|
||||
break;
|
||||
case AppStatusEnum.Missing:
|
||||
buttons.push(
|
||||
<Button onClick={onInstall} width={160} colorScheme="green" className="mt-3">
|
||||
Install
|
||||
</Button>,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
return (
|
||||
<div className="flex items-center sm:items-start flex-col md:flex-row">
|
||||
{buttons.map((button) => {
|
||||
return button;
|
||||
})}
|
||||
{renderStatus()}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AppActions;
|
||||
|
|
|
@ -1,26 +1,30 @@
|
|||
import { Modal, ModalBody, ModalCloseButton, ModalContent, ModalHeader, ModalOverlay } from '@chakra-ui/react';
|
||||
import { Button, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
import InstallForm from './InstallForm';
|
||||
import { App, AppInfo } from '../../../generated/graphql';
|
||||
import { AppInfo } from '../../../generated/graphql';
|
||||
|
||||
interface IProps {
|
||||
newVersion: string;
|
||||
app: AppInfo;
|
||||
config: App['config'];
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
onSubmit: (values: Record<string, any>) => void;
|
||||
onConfirm: () => void;
|
||||
}
|
||||
|
||||
const UpdateModal: React.FC<IProps> = ({ app, config, isOpen, onClose, onSubmit }) => {
|
||||
const UpdateModal: React.FC<IProps> = ({ app, newVersion, isOpen, onClose, onConfirm }) => {
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>Update {app.name} config</ModalHeader>
|
||||
<ModalHeader>Update {app.name} ?</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
<InstallForm onSubmit={onSubmit} formFields={app.form_fields} initalValues={config} />
|
||||
Update app to latest verion : <b>{newVersion}</b> ?
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button onClick={onConfirm} colorScheme="green">
|
||||
Update
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import { Modal, ModalBody, ModalCloseButton, ModalContent, ModalHeader, ModalOverlay } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
import InstallForm from './InstallForm';
|
||||
import { App, AppInfo } from '../../../generated/graphql';
|
||||
|
||||
interface IProps {
|
||||
app: AppInfo;
|
||||
config: App['config'];
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
onSubmit: (values: Record<string, any>) => void;
|
||||
}
|
||||
|
||||
const UpdateSettingsModal: React.FC<IProps> = ({ app, config, isOpen, onClose, onSubmit }) => {
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>Update {app.name} config</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
<InstallForm onSubmit={onSubmit} formFields={app.form_fields} initalValues={config} />
|
||||
</ModalBody>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default UpdateSettingsModal;
|
|
@ -6,7 +6,7 @@ import AppActions from '../components/AppActions';
|
|||
import InstallModal from '../components/InstallModal';
|
||||
import StopModal from '../components/StopModal';
|
||||
import UninstallModal from '../components/UninstallModal';
|
||||
import UpdateModal from '../components/UpdateModal';
|
||||
import UpdateSettingsModal from '../components/UpdateSettingsModal';
|
||||
import AppLogo from '../../../components/AppLogo/AppLogo';
|
||||
import Markdown from '../../../components/Markdown/Markdown';
|
||||
import {
|
||||
|
@ -20,10 +20,12 @@ import {
|
|||
useStopAppMutation,
|
||||
useUninstallAppMutation,
|
||||
useUpdateAppConfigMutation,
|
||||
useUpdateAppMutation,
|
||||
} from '../../../generated/graphql';
|
||||
import UpdateModal from '../components/UpdateModal';
|
||||
|
||||
interface IProps {
|
||||
app?: Pick<App, 'status' | 'config'>;
|
||||
app?: Pick<App, 'status' | 'config' | 'version' | 'updateInfo'>;
|
||||
info: AppInfo;
|
||||
}
|
||||
|
||||
|
@ -33,13 +35,17 @@ const AppDetails: React.FC<IProps> = ({ app, info }) => {
|
|||
const uninstallDisclosure = useDisclosure();
|
||||
const stopDisclosure = useDisclosure();
|
||||
const updateDisclosure = useDisclosure();
|
||||
const updateSettingsDisclosure = useDisclosure();
|
||||
|
||||
// Mutations
|
||||
const [update] = useUpdateAppMutation({ refetchQueries: [{ query: GetAppDocument, variables: { appId: info.id } }] });
|
||||
const [install] = useInstallAppMutation({ refetchQueries: [{ query: GetAppDocument, variables: { appId: info.id } }, { query: InstalledAppsDocument }] });
|
||||
const [uninstall] = useUninstallAppMutation({ refetchQueries: [{ query: GetAppDocument, variables: { appId: info.id } }, { query: InstalledAppsDocument }] });
|
||||
const [stop] = useStopAppMutation({ refetchQueries: [{ query: GetAppDocument, variables: { appId: info.id } }] });
|
||||
const [start] = useStartAppMutation({ refetchQueries: [{ query: GetAppDocument, variables: { appId: info.id } }] });
|
||||
const [update] = useUpdateAppConfigMutation({ refetchQueries: [{ query: GetAppDocument, variables: { appId: info.id } }] });
|
||||
const [updateConfig] = useUpdateAppConfigMutation({ refetchQueries: [{ query: GetAppDocument, variables: { appId: info.id } }] });
|
||||
|
||||
const updateAvailable = Number(app?.updateInfo?.current || 0) < Number(app?.updateInfo?.latest);
|
||||
|
||||
const { internalIp } = useSytemStore();
|
||||
|
||||
|
@ -93,16 +99,31 @@ const AppDetails: React.FC<IProps> = ({ app, info }) => {
|
|||
}
|
||||
};
|
||||
|
||||
const handleUpdateSubmit = async (values: Record<string, any>) => {
|
||||
const handleUpdateSettingsSubmit = async (values: Record<string, any>) => {
|
||||
try {
|
||||
await update({ variables: { input: { form: values, id: info.id } } });
|
||||
await updateConfig({ variables: { input: { form: values, id: info.id } } });
|
||||
toast({
|
||||
title: 'Success',
|
||||
description: 'App config updated successfully',
|
||||
position: 'top',
|
||||
status: 'success',
|
||||
});
|
||||
updateDisclosure.onClose();
|
||||
updateSettingsDisclosure.onClose();
|
||||
} catch (error) {
|
||||
handleError(error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdateSubmit = async () => {
|
||||
updateDisclosure.onClose();
|
||||
try {
|
||||
await update({ variables: { id: info.id }, optimisticResponse: { updateApp: { id: info.id, status: AppStatusEnum.Updating, __typename: 'App' } } });
|
||||
toast({
|
||||
title: 'Success',
|
||||
description: 'App updated successfully',
|
||||
position: 'top',
|
||||
status: 'success',
|
||||
});
|
||||
} catch (error) {
|
||||
handleError(error);
|
||||
}
|
||||
|
@ -121,6 +142,9 @@ const AppDetails: React.FC<IProps> = ({ app, info }) => {
|
|||
<div className="mt-3 items-center self-center flex flex-col sm:items-start sm:self-start md:mt-0">
|
||||
<h1 className="font-bold text-2xl">{info.name}</h1>
|
||||
<h2 className="text-center md:text-left">{info.short_desc}</h2>
|
||||
<h3 className="text-center md:text-left text-sm">
|
||||
version: <b>{info.version}</b> ({app?.version})
|
||||
</h3>
|
||||
{info.source && (
|
||||
<a target="_blank" rel="noreferrer" className="text-blue-500 text-xs" href={info.source}>
|
||||
<Flex className="mt-2 items-center">
|
||||
|
@ -133,7 +157,9 @@ const AppDetails: React.FC<IProps> = ({ app, info }) => {
|
|||
</div>
|
||||
<div className="flex justify-center xs:absolute md:static top-0 right-5 self-center sm:self-auto">
|
||||
<AppActions
|
||||
updateAvailable={updateAvailable}
|
||||
onUpdate={updateDisclosure.onOpen}
|
||||
onUpdateSettings={updateSettingsDisclosure.onOpen}
|
||||
onOpen={handleOpen}
|
||||
onStart={handleStartSubmit}
|
||||
onStop={stopDisclosure.onOpen}
|
||||
|
@ -151,7 +177,8 @@ const AppDetails: React.FC<IProps> = ({ app, info }) => {
|
|||
<InstallModal onSubmit={handleInstallSubmit} isOpen={installDisclosure.isOpen} onClose={installDisclosure.onClose} app={info} />
|
||||
<UninstallModal onConfirm={handleUnistallSubmit} isOpen={uninstallDisclosure.isOpen} onClose={uninstallDisclosure.onClose} app={info} />
|
||||
<StopModal onConfirm={handleStopSubmit} isOpen={stopDisclosure.isOpen} onClose={stopDisclosure.onClose} app={info} />
|
||||
<UpdateModal onSubmit={handleUpdateSubmit} isOpen={updateDisclosure.isOpen} onClose={updateDisclosure.onClose} app={info} config={app?.config} />
|
||||
<UpdateSettingsModal onSubmit={handleUpdateSettingsSubmit} isOpen={updateSettingsDisclosure.isOpen} onClose={updateSettingsDisclosure.onClose} app={info} config={app?.config} />
|
||||
<UpdateModal onConfirm={handleUpdateSubmit} isOpen={updateDisclosure.isOpen} onClose={updateDisclosure.onClose} app={info} newVersion={`${info.version} (${info.tipi_version})`} />
|
||||
</div>
|
||||
</SlideFade>
|
||||
);
|
||||
|
|
|
@ -12,7 +12,7 @@ const AppDetailsPage: NextPage<IProps> = ({ appId }) => {
|
|||
|
||||
const breadcrumb = [
|
||||
{ name: 'Apps', href: '/apps' },
|
||||
{ name: data?.getApp.info.name || '', href: `/apps/${appId}`, current: true },
|
||||
{ name: data?.getApp.info?.name || '', href: `/apps/${appId}`, current: true },
|
||||
];
|
||||
|
||||
return (
|
||||
|
|
|
@ -3,13 +3,19 @@ import { Flex, SimpleGrid } from '@chakra-ui/react';
|
|||
import type { NextPage } from 'next';
|
||||
import Layout from '../../components/Layout';
|
||||
import AppTile from '../../components/AppTile';
|
||||
import { useInstalledAppsQuery } from '../../generated/graphql';
|
||||
import { InstalledAppsQuery, useInstalledAppsQuery } from '../../generated/graphql';
|
||||
|
||||
const Apps: NextPage = () => {
|
||||
const { data, loading } = useInstalledAppsQuery();
|
||||
|
||||
const installedCount: number = data?.installedApps.length || 0;
|
||||
|
||||
const renderApp = (app: InstalledAppsQuery['installedApps'][0]) => {
|
||||
const updateAvailable = Number(app.updateInfo?.current) < Number(app.updateInfo?.latest);
|
||||
|
||||
if (app.info) return <AppTile key={app.id} app={app.info} status={app.status} updateAvailable={updateAvailable} />;
|
||||
};
|
||||
|
||||
return (
|
||||
<Layout loading={loading || !data?.installedApps}>
|
||||
<Flex className="flex-col">
|
||||
|
@ -21,9 +27,7 @@ const Apps: NextPage = () => {
|
|||
</div>
|
||||
)}
|
||||
<SimpleGrid minChildWidth="340px" spacing="20px">
|
||||
{data?.installedApps.map((app) => (
|
||||
<AppTile key={app.id} app={app.info} status={app.status} />
|
||||
))}
|
||||
{data?.installedApps.map((a) => renderApp(a))}
|
||||
</SimpleGrid>
|
||||
</Flex>
|
||||
</Layout>
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
const objectKeys = <T>(obj: T): (keyof T)[] => Object.keys(obj) as (keyof T)[];
|
||||
|
||||
export { objectKeys };
|
||||
function nonNullable<T>(value: T): value is NonNullable<T> {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
export { objectKeys, nonNullable };
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AppStatusUpdating1660071627328 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('ALTER TYPE "public"."app_status_enum" ADD VALUE \'updating\'');
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('ALTER TYPE "public"."app_status_enum" DROP VALUE \'updating\'');
|
||||
}
|
||||
}
|
|
@ -1,13 +1,22 @@
|
|||
import { GraphQLJSONObject } from 'graphql-type-json';
|
||||
import { Field, ObjectType, registerEnumType } from 'type-graphql';
|
||||
import { BaseEntity, Column, CreateDateColumn, Entity, UpdateDateColumn } from 'typeorm';
|
||||
import { getAppInfo } from './apps.helpers';
|
||||
import { getAppInfo, getUpdateInfo } from './apps.helpers';
|
||||
import { AppInfo, AppStatusEnum } from './apps.types';
|
||||
|
||||
registerEnumType(AppStatusEnum, {
|
||||
name: 'AppStatusEnum',
|
||||
});
|
||||
|
||||
@ObjectType()
|
||||
class UpdateInfo {
|
||||
@Field(() => Number)
|
||||
current!: number;
|
||||
|
||||
@Field(() => Number)
|
||||
latest!: number;
|
||||
}
|
||||
|
||||
@ObjectType()
|
||||
@Entity()
|
||||
class App extends BaseEntity {
|
||||
|
@ -43,10 +52,15 @@ class App extends BaseEntity {
|
|||
@UpdateDateColumn()
|
||||
updatedAt!: Date;
|
||||
|
||||
@Field(() => AppInfo)
|
||||
info(): AppInfo {
|
||||
@Field(() => AppInfo, { nullable: true })
|
||||
info(): AppInfo | null {
|
||||
return getAppInfo(this.id);
|
||||
}
|
||||
|
||||
@Field(() => UpdateInfo, { nullable: true })
|
||||
updateInfo(): Promise<UpdateInfo | null> {
|
||||
return getUpdateInfo(this.id);
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -5,6 +5,7 @@ import crypto from 'crypto';
|
|||
import config from '../../config';
|
||||
import { AppInfo } from './apps.types';
|
||||
import logger from '../../config/logger/logger';
|
||||
import App from './app.entity';
|
||||
|
||||
export const checkAppRequirements = async (appName: string) => {
|
||||
let valid = true;
|
||||
|
@ -136,6 +137,13 @@ export const getAvailableApps = async (): Promise<string[]> => {
|
|||
export const getAppInfo = (id: string): AppInfo => {
|
||||
try {
|
||||
const repoId = config.APPS_REPO_ID;
|
||||
|
||||
if (fileExists(`/apps/${id}/config.json`)) {
|
||||
const configFile: AppInfo = readJsonFile(`/apps/${id}/config.json`);
|
||||
configFile.description = readFile(`/apps/${id}/metadata/description.md`).toString();
|
||||
return configFile;
|
||||
}
|
||||
|
||||
if (fileExists(`/repos/${repoId}`)) {
|
||||
const configFile: AppInfo = readJsonFile(`/repos/${repoId}/apps/${id}/config.json`);
|
||||
configFile.description = readFile(`/repos/${repoId}/apps/${id}/metadata/description.md`);
|
||||
|
@ -150,3 +158,18 @@ export const getAppInfo = (id: string): AppInfo => {
|
|||
throw new Error(`Error loading app ${id}`);
|
||||
}
|
||||
};
|
||||
|
||||
export const getUpdateInfo = async (id: string) => {
|
||||
const app = await App.findOne({ where: { id } });
|
||||
|
||||
if (!app) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const repoConfig: AppInfo = readJsonFile(`/repos/${config.APPS_REPO_ID}/apps/${id}/config.json`);
|
||||
|
||||
return {
|
||||
current: app.version,
|
||||
latest: repoConfig.tipi_version,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -54,4 +54,10 @@ export default class AppsResolver {
|
|||
|
||||
return AppsService.updateAppConfig(id, form);
|
||||
}
|
||||
|
||||
@Authorized()
|
||||
@Mutation(() => App)
|
||||
async updateApp(@Arg('id', () => String) id: string): Promise<App> {
|
||||
return AppsService.updateApp(id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -185,4 +185,30 @@ const getApp = async (id: string): Promise<App> => {
|
|||
return app;
|
||||
};
|
||||
|
||||
export default { installApp, startApp, listApps, getApp, updateAppConfig, stopApp, uninstallApp, startAllApps };
|
||||
const updateApp = async (id: string) => {
|
||||
let app = await App.findOne({ where: { id } });
|
||||
|
||||
if (!app) {
|
||||
throw new Error(`App ${id} not found`);
|
||||
}
|
||||
|
||||
await App.update({ id }, { status: AppStatusEnum.UPDATING });
|
||||
|
||||
// Run script
|
||||
try {
|
||||
await runAppScript(['update', id]);
|
||||
const appInfo: AppInfo | null = await readJsonFile(`/apps/${id}/config.json`);
|
||||
await App.update({ id }, { status: AppStatusEnum.RUNNING, version: Number(appInfo?.tipi_version) });
|
||||
} catch (e) {
|
||||
logger.error(e);
|
||||
throw e;
|
||||
} finally {
|
||||
await App.update({ id }, { status: AppStatusEnum.STOPPED });
|
||||
}
|
||||
|
||||
app = (await App.findOne({ where: { id } })) as App;
|
||||
|
||||
return app;
|
||||
};
|
||||
|
||||
export default { installApp, startApp, updateApp, listApps, getApp, updateAppConfig, stopApp, uninstallApp, startAllApps };
|
||||
|
|
|
@ -37,6 +37,7 @@ export enum AppStatusEnum {
|
|||
STOPPING = 'stopping',
|
||||
STARTING = 'starting',
|
||||
MISSING = 'missing',
|
||||
UPDATING = 'updating',
|
||||
}
|
||||
|
||||
registerEnumType(AppCategoriesEnum, {
|
||||
|
|
|
@ -189,7 +189,6 @@ if [[ "$command" = "update" ]]; then
|
|||
cp -r "${ROOT_FOLDER}/repos/${repo_id}/apps/${app}" "${app_dir}"
|
||||
|
||||
compose "${app}" pull
|
||||
compose "${app}" up --detach
|
||||
exit
|
||||
fi
|
||||
|
||||
|
|
Loading…
Reference in a new issue