Skip to content

Commit

Permalink
Merge branch 'next' into submit-extension1
Browse files Browse the repository at this point in the history
  • Loading branch information
quininez committed Sep 20, 2024
2 parents 9ba673c + caa7553 commit ce8da19
Show file tree
Hide file tree
Showing 17 changed files with 394 additions and 99 deletions.
16 changes: 14 additions & 2 deletions .github/workflows/sdk.publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
- next
paths:
- "libs/sdk/package.json"
- "libs/typings/package.json"
- "libs/composedb/package.json"
jobs:
build:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -39,9 +41,19 @@ jobs:
run: |
yarn install --immutable
- run: echo "${GITHUB_WORKSPACE}/node_modules/.bin" >> $GITHUB_PATH
- run: nx run @akashaorg/core-sdk:prepare-publish
- run: nx run-many --target=prepare-publish --all --verbose
- name: Publish @akashaorg/core-sdk
working-directory: dist/npm/core-sdk
run: npm publish --provenance
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ env.NPM_TOKEN }}
- name: Publish @akashaorg/typings
working-directory: dist/npm/typings
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ env.NPM_TOKEN }}
- name: Publish @akashaorg/composedb-models
working-directory: dist/npm/composedb
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ env.NPM_TOKEN }}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@ import ErrorLoader from '@akashaorg/design-system-core/lib/components/ErrorLoade
import Button from '@akashaorg/design-system-core/lib/components/Button';
import { useGetAppsByPublisherDidQuery } from '@akashaorg/ui-awf-hooks/lib/generated';
import getSDK from '@akashaorg/core-sdk';
import { SortOrder } from '@akashaorg/typings/lib/sdk/graphql-types-new';
import {
AkashaAppApplicationType,
AkashaAppEdge,
SortOrder,
} from '@akashaorg/typings/lib/sdk/graphql-types-new';
import { GetAppsByPublisherDidQuery } from '@akashaorg/typings/lib/sdk/graphql-operation-types-new';
import { getReportedError, getReportedProgress } from './utils';
import { AkashaProfile } from '@akashaorg/typings/lib/ui';
import { useNavigate } from '@tanstack/react-router';

export const InstallExtensionPage = ({ appId }: { appId: string }) => {
const { t } = useTranslation('app-extensions');
const { decodeAppName, getCorePlugins } = useRootComponentProps();
const { decodeAppName, getCorePlugins, plugins, logger } = useRootComponentProps();
const decodeName = React.useRef(decodeAppName);
const installer = getCorePlugins().extensionInstaller;
const installerStatusCodes = React.useRef(installer.getStaticStatusCodes());
Expand All @@ -23,7 +29,9 @@ export const InstallExtensionPage = ({ appId }: { appId: string }) => {
const [reportedStatus, setReportedStatus] = useState<symbol>();
const [reportedError, setReportedError] = useState<{ code: symbol; retryable: boolean }>(null);
const [shouldRegisterResources, setShouldRegisterResources] = useState<boolean>(false);
const [authorProfileData, setAuthorProfileData] = React.useState<AkashaProfile>(null);
const idxDid = getSDK().services.gql.indexingDID;
const navigate = useNavigate();

const {
data: { authenticatedDID, isAuthenticating },
Expand All @@ -38,6 +46,26 @@ export const InstallExtensionPage = ({ appId }: { appId: string }) => {
},
});

const appAuthorId = useMemo(() => {
if (data) {
return selectAppPublisherProfile(data).id;
}
}, [data]);

useEffect(() => {
const getAuthorProfile = async () => {
if (appAuthorId && plugins['@akashaorg/app-profile']) {
const resp = await plugins['@akashaorg/app-profile'].profile.getProfileInfo({
profileDID: appAuthorId,
});
if (resp.data) {
setAuthorProfileData(resp.data);
}
}
};
getAuthorProfile().catch(err => logger.warn(err));
}, [appAuthorId, logger, plugins]);

const retryableError: symbol[] = useMemo(
() => [
installerStatusCodes.current.error.EXTENSION_FETCH_ERROR,
Expand Down Expand Up @@ -72,6 +100,22 @@ export const InstallExtensionPage = ({ appId }: { appId: string }) => {
}
}, [installer, shouldRegisterResources]);

useEffect(() => {
let timeout;
if (isInstalled) {
// navigation using replace it's important here
// because we also want to refresh the page
timeout = setTimeout(() => {
window.location.replace(`/${decodeName.current(appId)}`);
}, 3000);
}
return () => {
if (timeout) {
clearTimeout(timeout);
}
};
}, [appId, isInstalled]);

useEffect(() => {
const startInstaller = async () => {
const appName = decodeName.current(appId);
Expand All @@ -82,20 +126,29 @@ export const InstallExtensionPage = ({ appId }: { appId: string }) => {
.installedExtensions.where({ appName })
.first();
if (!appLocalData) {
console.error('Terms not accepted, redirect to terms....');
navigate({
to: '/install/$appId/terms',
params: { appId },
replace: true,
}).catch(err => logger.error('Failed to navigate: %o', err));
return;
}
if (appLocalData?.termsAccepted) {
isInstalling.current = true;
await installer.installExtension(appName);
} else {
console.error(appLocalData, 'Terms not accepted, redirect to terms...');
navigate({
to: '/install/$appId/terms',
params: { appId },
replace: true,
}).catch(err => logger.error('Failed to navigate: %o', err));
}
}
};
if (authenticatedDID) {
startInstaller();
startInstaller().catch(err => logger.error(err));
}
}, [appId, authenticatedDID, installer]);
}, [appId, authenticatedDID, installer, logger, navigate]);

useEffect(() => {
return installer.subscribe(
Expand Down Expand Up @@ -161,51 +214,63 @@ export const InstallExtensionPage = ({ appId }: { appId: string }) => {
if (reportedError?.code) {
return 'error';
}
if (shouldRegisterResources && 1 < 0 /* successfullySigned */) {
return 'complete';
}
if (shouldRegisterResources) {
return 'authorize-request';
}
return 'in-progress';
}, [isInstalled, reportedError]);
}, [isInstalled, reportedError?.code, shouldRegisterResources]);

const progressInfo = useMemo(() => {
if (isInstalled) {
return `${t('Application {{displayName}} successfully installed.', {
displayName: getAppDisplayName(data),
})}`;
return `${t(
'Extension {{displayName}} has been installed. The page will refresh and load it.',
{
displayName: selectAppDisplayName(data),
},
)}`;
}
if (reportedError?.code) {
return getReportedError(reportedError, installerStatusCodes.current.error, t);
}
return getReportedProgress(reportedStatus, installerStatusCodes.current.status, t);
}, [data, isInstalled, reportedError, reportedStatus, t]);

const action = useMemo(() => {
const successLabel = useMemo(() => {
if (isInstalled) {
return {
label: t('Open the app'),
return t('Finished');
}
if (shouldRegisterResources && 1 < 0 /*successfullySigned*/) {
return t('Request authorised');
}
}, [isInstalled, shouldRegisterResources, t]);

const actions = useMemo(() => {
if (isInstalled) {
return;
}
const actions = [];
if (shouldRegisterResources) {
actions.push({
label: t('Authorise'),
onClick: () => {
getCorePlugins().routing.navigateTo({
appName: decodeName.current(appId),
});
logger.info('Authorise new resources');
},
};
});
}
if (reportedError?.code && reportedError?.retryable) {
return {
actions.push({
label: t('Retry'),
onClick: () => installer.retryFromError(reportedError.code),
};
});
}
return {
return actions.concat({
label: t('Cancel installation'),
onClick: () => installer.cancelInstallation(),
};
}, [
appId,
getCorePlugins,
installer,
isInstalled,
reportedError?.code,
reportedError?.retryable,
t,
]);
});
}, [installer, isInstalled, logger, reportedError, shouldRegisterResources, t]);

if (error) {
return (
Expand All @@ -216,35 +281,67 @@ export const InstallExtensionPage = ({ appId }: { appId: string }) => {
/>
);
}

return (
<>
{(isAuthenticating || loading) && <div>Loading...</div>}
{!authenticatedDID && !isAuthenticating && called && !loading && (
<ErrorLoader
type="not-authenticated"
title={t('Login Required')}
details={t('You must be logged in to install {{appDisplayName}}', {
appDisplayName: getAppDisplayName(data),
appDisplayName: selectAppDisplayName(data),
})}
>
<Button label={t('Login')} onClick={handleLoginClick} />
</ErrorLoader>
)}
{authenticatedDID && called && !loading && (
<InstallApp
title={isInstalled ? t('Application installed') : t('Installation in progress')}
appName={getAppDisplayName(data)}
title={isInstalled ? t('Installation complete') : t('Installation in progress')}
appName={selectAppDisplayName(data)}
appAvatar={selectAppAvatar(data)}
publisherName={authorProfileData?.name}
publisherDID={appAuthorId}
appType={selectAppType(data) ?? AkashaAppApplicationType.App}
progressInfo={progressInfo}
status={installStatus}
action={action}
actions={actions}
successLabel={successLabel}
/>
)}
</>
);
};

const getAppDisplayName = (respData: GetAppsByPublisherDidQuery) => {
if (respData?.node && 'akashaAppList' in respData.node) {
const hasAppListNode = (
respData: GetAppsByPublisherDidQuery,
): respData is { node: { akashaAppList: { edges: AkashaAppEdge[] } } } => {
return (
respData.node &&
'akashaAppList' in respData.node &&
Array.isArray(respData.node.akashaAppList.edges)
);
};

const selectAppDisplayName = (respData: GetAppsByPublisherDidQuery) => {
if (hasAppListNode(respData)) {
return respData.node.akashaAppList.edges[0]?.node.displayName;
}
};

const selectAppAvatar = (respData: GetAppsByPublisherDidQuery) => {
if (hasAppListNode(respData)) {
return respData.node.akashaAppList.edges[0]?.node.logoImage;
}
};

const selectAppPublisherProfile = (respData: GetAppsByPublisherDidQuery) => {
if (hasAppListNode(respData)) {
return respData.node.akashaAppList.edges[0]?.node.author;
}
};
const selectAppType = (respData: GetAppsByPublisherDidQuery) => {
if (hasAppListNode(respData)) {
return respData.node.akashaAppList.edges[0]?.node.applicationType;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,23 @@ export const getReportedProgress = (
) => {
switch (reportedStatus) {
case statusCodes.FETCHING_EXTENSION_DATA:
return tFunc('Fetching extension data');
return tFunc('Retrieving latest release info...');
case statusCodes.IMPORTING_MODULE:
return tFunc('Importing module');
return tFunc('Importing extension modules...');
case statusCodes.INITIALIZING_EXTENSION:
return tFunc('Initializing extension');
return tFunc('Initializing extension...');
case statusCodes.REGISTERING_EXTENSION:
return tFunc('Registering extension');
return tFunc('Registering extension and it`s plugins...');
case statusCodes.SAVING_EXTENSION_INFO:
return tFunc('Saving extension info');
return tFunc('Saving configuration...');
case statusCodes.FINALIZING_INSTALL:
return tFunc('Finalizing install');
return tFunc('Finalizing install...');
case statusCodes.REGISTERING_RESOURCES:
return tFunc('Registering resources');
return tFunc(
'Click the button below to authorise access to new resources. You will be prompted with 1 signature.',
);
case statusCodes.REGISTERING_RESOURCES_SUCCESS:
return tFunc('Registering resources success');
return tFunc('You have authorised new resources. Continuing installation...');
}
return '';
};
Expand All @@ -97,33 +99,31 @@ export const getReportedError = (
let errorMessage = '';
switch (reportedError.code) {
case statusCodes.USER_NOT_CONNECTED:
errorMessage = tFunc('You need to login.');
errorMessage = tFunc('You need to login to install new extensions.');
break;
case statusCodes.EXTENSION_NOT_FOUND:
errorMessage = tFunc('Extension was not found in the Extensions Registry.');
break;
case statusCodes.EXTENSION_FETCH_ERROR:
errorMessage = tFunc('Cannot fetch extension information. Please try again.');
errorMessage = tFunc('Failed to retrieve release info.');
break;
case statusCodes.EXTENSION_DATA_INVALID:
errorMessage = tFunc('Extension is not valid.');
errorMessage = tFunc('Extension or release data is not valid.');
break;
case statusCodes.EXTENSION_IMPORT_ERROR:
errorMessage = tFunc('Failed to import the extension. Please try again.');
errorMessage = tFunc('Failed to import the extension.');
break;
case statusCodes.EXTENSION_INITIALIZATION_FAILED:
errorMessage = tFunc('Failed to initialize extension. Please try again.');
errorMessage = tFunc('Failed to initialize extension.');
break;
case statusCodes.EXTENSION_REGISTER_RESOURCES_FAILED:
errorMessage = tFunc('Failed to register new resources for the extension. Please try again.');
errorMessage = tFunc('Failed to register new resources for the extension.');
break;
case statusCodes.EXTENSION_REGISTRATION_FAILED:
errorMessage = tFunc('Failed to register the extension. Please try again.');
errorMessage = tFunc('Failed to register the extension.');
break;
case statusCodes.EXTENSION_INFO_SAVE_FAILED:
errorMessage = tFunc(
'Failed to save extension information to local database. Please try again.',
);
errorMessage = tFunc('Failed to save extension information to local database.');
break;
case statusCodes.EXTENSION_FINALIZATION_FAILED:
errorMessage = tFunc(
Expand Down
Loading

0 comments on commit ce8da19

Please sign in to comment.