Skip to content

Commit

Permalink
WIP app new drive creation;
Browse files Browse the repository at this point in the history
  • Loading branch information
stef-coenen committed Jan 5, 2024
1 parent 485f054 commit 430d6f4
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 40 deletions.
49 changes: 46 additions & 3 deletions packages/common-app/src/hooks/posts/channels/useChannel.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
ChannelDefinition,
GetTargetDriveFromChannelId,
getChannelDefinition,
getChannelDefinitionBySlug,
removeChannelDefinition,
Expand All @@ -10,9 +11,15 @@ import {
import { useStaticFiles } from '@youfoundation/common-app';
import { ChannelDefinitionVm, parseChannelTemplate } from './useChannels';
import { useDotYouClient } from '../../../..';
import { stringGuidsEqual } from '@youfoundation/js-lib/helpers';
import { stringGuidsEqual, stringifyToQueryParams, toGuidId } from '@youfoundation/js-lib/helpers';
import { fetchCachedPublicChannels } from '../cachedDataHelpers';
import { DriveSearchResult, NewDriveSearchResult } from '@youfoundation/js-lib/core';
import {
DrivePermissionType,
DriveSearchResult,
NewDriveSearchResult,
} from '@youfoundation/js-lib/core';
import { ROOT_PATH } from '@youfoundation/feed-app/src/app/App';
import { FEED_APP_ID } from '../../../../../owner-app/src/app/Constants';

type useChannelsProps = {
channelSlug?: string;
Expand Down Expand Up @@ -73,7 +80,43 @@ export const useChannel = ({ channelSlug, channelId }: useChannelsProps) => {
const saveData = async (
channelDef: NewDriveSearchResult<ChannelDefinition> | DriveSearchResult<ChannelDefinition>
) => {
await saveChannelDefinition(dotYouClient, { ...channelDef });
if (!channelDef.fileId) {
if (!channelDef.fileMetadata.appData.uniqueId) {
channelDef.fileMetadata.appData.uniqueId = toGuidId(
channelDef.fileMetadata.appData.content.name
);
}
const identity = dotYouClient.getIdentity();
const returnUrl = `${ROOT_PATH}/channels?${JSON.stringify(channelDef)}`;

const targetDrive = GetTargetDriveFromChannelId(channelDef.fileMetadata.appData.uniqueId);

const drives = [
{
a: targetDrive.alias,
t: targetDrive.type,
p:
DrivePermissionType.Read +
DrivePermissionType.Write +
DrivePermissionType.React +
DrivePermissionType.Comment, // Permission
n: channelDef.fileMetadata.appData.content.name, // Name
d: '',
},
];

const params = {
appId: FEED_APP_ID,
d: JSON.stringify(drives),
};

const targetUrl = `https://${identity}/owner/app-new-drive?${stringifyToQueryParams(
params
)}&return=${encodeURIComponent(returnUrl)}`;
window.location.href = targetUrl;
} else {
return await saveChannelDefinition(dotYouClient, { ...channelDef });
}
};

const removeChannel = async (channelDef: DriveSearchResult<ChannelDefinition>) => {
Expand Down
43 changes: 6 additions & 37 deletions packages/owner-app/src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ const YouAuthConsent = lazy(() => import('../templates/YouAuthConsent/YouAuthCon
const Setup = lazy(() => import('../templates/Setup/Setup').then((m) => ({ default: m.Setup })));

const Home = lazy(() => import('../templates/Dashboard/Dashboard'));
const RegisterAppClient = lazy(() => import('../templates/RegisterApp/RegisterApp'));
const RegisterApp = lazy(() => import('../templates/AppDefinition/RegisterApp'));
const ExtendAppDrivePermissions = lazy(
() => import('../templates/AppDefinition/ExtendAppDrivePermissions')
);
const Login = lazy(() => import('../templates/Login/Login'));
const AccountRecovery = lazy(() => import('../templates/AccountRecovery/AccountRecovery'));
const FirstRun = lazy(() => import('../templates/FirstRun/FirstRun'));
Expand Down Expand Up @@ -49,27 +52,6 @@ const Settings = lazy(() => import('../templates/Settings/Settings'));
const DemoData = lazy(() => import('../templates/DemoData/DemoData'));
const Debug = lazy(() => import('../templates/Debug/Debug'));

const SocialFeed = lazy(() =>
import('@youfoundation/feed-app/src/templates/SocialFeed/SocialFeed').then((feedApp) => ({
default: feedApp.SocialFeed,
}))
);
const ArticlesPage = lazy(() =>
import('@youfoundation/feed-app/src/templates/SocialFeed/ArticlesPage').then((feedApp) => ({
default: feedApp.ArticlesPage,
}))
);
const ChannelsPage = lazy(() =>
import('@youfoundation/feed-app/src/templates/SocialFeed/ChannelsPage').then((feedApp) => ({
default: feedApp.ChannelsPage,
}))
);
const ArticleComposerPage = lazy(() =>
import('@youfoundation/feed-app/src/templates/SocialFeed/ArticleComposerPage').then(
(feedApp) => ({ default: feedApp.ArticleComposerPage })
)
);

import '@youfoundation/ui-lib/dist/style.css';
import './App.css';
import LoadingDetailPage from '../components/ui/Loaders/LoadingDetailPage/LoadingDetailPage';
Expand Down Expand Up @@ -146,7 +128,8 @@ function App() {
</MinimalLayout>
}
>
<Route path="appreg" element={<RegisterAppClient />} />
<Route path="appreg" element={<RegisterApp />} />
<Route path="app-new-drive" element={<ExtendAppDrivePermissions />} />
</Route>

<Route
Expand Down Expand Up @@ -200,20 +183,6 @@ function App() {

<Route path="demo-data" element={<DemoData />}></Route>
<Route path="debug" element={<Debug />}></Route>

{/* Feed: */}
<Route path="feed">
<Route index={true} element={<SocialFeed />} />
<Route path="preview/:identityKey/:channelKey/:postKey" element={<SocialFeed />} />
<Route
path="preview/:identityKey/:channelKey/:postKey/:attachmentKey"
element={<SocialFeed />}
/>
<Route path="new" element={<ArticleComposerPage />} />
<Route path="articles" element={<ArticlesPage />} />
<Route path="channels" element={<ChannelsPage />} />
<Route path="edit/:channelKey/:postKey" element={<ArticleComposerPage />} />
</Route>
</Route>

<Route
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { tryJsonParse } from '@youfoundation/js-lib/helpers';
import { DriveGrantRequest } from '../../provider/app/AppManagementProviderTypes';
import { useSearchParams } from 'react-router-dom';
import { ActionButton, Arrow, t } from '@youfoundation/common-app';
import Section from '../../components/ui/Sections/Section';
import DrivePermissionRequestView from '../../components/PermissionViews/DrivePermissionRequestView/DrivePermissionRequestView';
import { useApp } from '../../hooks/apps/useApp';
import { useDrives } from '../../hooks/drives/useDrives';

const ExtendAppDrivePermissions = () => {
// Read the queryString
const [searchParams] = useSearchParams();

const appId = searchParams.get('appId');
const returnUrl = searchParams.get('return');

const d = searchParams.get('d');
const driveGrants = d ? drivesParamToDriveGrantRequest(d) : undefined;

console.log({ driveGrants });

const {
fetch: { data: appRegistration },
updatePermissions: { status: updatePermissionStatus },
} = useApp({ appId: appId || undefined });

const doUpdateApp = async () => {
// Ensure drives
// Update app
// Redirect
};

const doCancel = async () => {
// Redirect
window.location.href = returnUrl || '/';
};

const { data: existingDrives } = useDrives().fetch;
const existingDriveGrants = driveGrants?.filter(
(grant) =>
existingDrives?.some(
(drive) =>
drive.targetDriveInfo.alias === grant.permissionedDrive.drive.alias &&
drive.targetDriveInfo.type === grant.permissionedDrive.drive.type
)
);

const newDriveGrants = driveGrants?.filter(
(grant) =>
!existingDrives?.some(
(drive) =>
drive.targetDriveInfo.alias === grant.permissionedDrive.drive.alias &&
drive.targetDriveInfo.type === grant.permissionedDrive.drive.type
)
);

return (
<>
<section className="my-20">
<div className="container mx-auto">
<div className="max-w-[35rem]">
<h1 className="mb-5 text-4xl dark:text-white">
{t('Update existing app')}:<small className="block">{appRegistration?.name}</small>
</h1>

<p>
{t('The app')} &quot;{appRegistration?.name}&quot;{' '}
{t('has requested extra access on your identity')}.
</p>
<p className="mt-2">
{t('By allowing, this app')}, &quot;{appRegistration?.name}&quot;{' '}
{t('will receive the following access on your identity')}:
</p>

<Section>
{existingDriveGrants?.length ? (
<div className="flex flex-col gap-4">
{existingDriveGrants.map((grant) => (
<DrivePermissionRequestView
key={`${grant.permissionedDrive.drive.alias}-${grant.permissionedDrive.drive.type}`}
driveGrant={grant}
/>
))}
</div>
) : (
<p className="text-slate-400">{t('No changes to existing drive access')}</p>
)}
</Section>

{newDriveGrants?.length ? (
<>
<p>{t('Requests these new drives')}</p>
<Section>
<div className="flex flex-col gap-4">
{newDriveGrants.map((grant) => (
<DrivePermissionRequestView
key={`${grant.permissionedDrive.drive.alias}-${grant.permissionedDrive.drive.type}`}
driveGrant={grant}
/>
))}
</div>
</Section>
</>
) : null}

<div className="flex flex-col items-center gap-2 sm:flex-row-reverse">
<ActionButton
onClick={doUpdateApp}
type="primary"
state={updatePermissionStatus}
icon={Arrow}
>
{t('Allow')}
</ActionButton>

<ActionButton type="secondary" onClick={() => doCancel()}>
{t('Cancel')}
</ActionButton>
</div>
</div>
</div>
</section>
</>
);
};

const drivesParamToDriveGrantRequest = (queryParamVal: string | undefined): DriveGrantRequest[] => {
if (!queryParamVal) {
return [];
}
try {
const drivesParamObject = queryParamVal && tryJsonParse(queryParamVal);
return (Array.isArray(drivesParamObject) ? drivesParamObject : [drivesParamObject]).map((d) => {
return {
permissionedDrive: {
drive: {
alias: d.a,
type: d.t,
},
// I know, probably not really "safe" to do this... But hey, the drivePermission are hard
permission: [parseInt(d.p)],
},
driveMeta: {
name: d.n,
description: d.d,
},
};
});
} catch (ex) {
return [];
}
};

export default ExtendAppDrivePermissions;

0 comments on commit 430d6f4

Please sign in to comment.