Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ms2/share modal improvements 2 #446

Merged
merged 14 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,98 +1,109 @@
'use client';
import { useEffect, useState } from 'react';
import { CopyOutlined } from '@ant-design/icons';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit-Pick:
Replace with
import { IoMdCopy } from "react-icons/io";
to align with new Buttons

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will do this in the next PR

import { Button, Input, Checkbox, App } from 'antd';
import { Button, Input, Checkbox, App, Select, Space, Result, message } from 'antd';
import { useParams, useSearchParams } from 'next/navigation';
import {
generateSharedViewerUrl,
updateProcessGuestAccessRights,
} from '@/lib/sharing/process-sharing';
import { useEnvironment } from '@/components/auth-can';
import { Process } from '@/lib/data/process-schema';
import { wrapServerCall } from '@/lib/wrap-server-call';
import { isUserErrorResponse } from '@/lib/user-error';

const { TextArea } = Input;

type ModelerShareModalOptionEmdedInWebProps = {
sharedAs: 'public' | 'protected';
allowIframeTimestamp: number;
refresh: () => void;
processVersions: Process['versions'];
};

const ModelerShareModalOptionEmdedInWeb = ({
sharedAs,
allowIframeTimestamp,
refresh,
processVersions,
}: ModelerShareModalOptionEmdedInWebProps) => {
const app = App.useApp();
const { processId } = useParams();
const environment = useEnvironment();
const [embeddingUrl, setEmbeddingUrl] = useState('');
const { message } = App.useApp();

const query = useSearchParams();
const selectedVersionId = query.get('version');
const [selectedVersionId, setSelectedVersionId] = useState<string | null>(() => {
const queryVersion = query.get('version');
if (queryVersion && processVersions.find((version) => version.id === queryVersion))
return queryVersion;
else return processVersions[0]?.id;
});

useEffect(() => {
const initialize = async () => {
if (allowIframeTimestamp > 0) {
try {
// generate an url with a token that contains the currently active embedding timestamp
const url = await generateSharedViewerUrl(
if (allowIframeTimestamp > 0 && selectedVersionId) {
wrapServerCall({
fn: () =>
generateSharedViewerUrl(
{
processId,
embeddedMode: true,
timestamp: allowIframeTimestamp,
},
selectedVersionId || undefined,
);
setEmbeddingUrl(url);
} catch (error) {
console.error('Error while generating the url for embedding:', error);
}
}
};
initialize();
}, [allowIframeTimestamp, environment.spaceId, processId, sharedAs, selectedVersionId]);
selectedVersionId,
),
onSuccess: (url) => setEmbeddingUrl(url),
app,
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit-Pick:
Really like the easy way to add some feedback to the user in case of an error with your wrapServerCall, I don't see a reason why one should not use it here as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get what you mean, are you saying that I should wrap setEmbeddingUrl in a wrapSeverCall?

}
}, [allowIframeTimestamp, environment.spaceId, processId, sharedAs, selectedVersionId, app]);

const handleAllowEmbeddingChecked = async (e: {
target: { checked: boolean | ((prevState: boolean) => boolean) };
}) => {
const isChecked = e.target.checked;
if (isChecked) {
try {
const timestamp = Date.now();
// generate an url containing a token with the newly generated timestamp
const url = await generateSharedViewerUrl(
{
// create embedding
const timestamp = Date.now();
await wrapServerCall({
fn: async () => {
const url = await generateSharedViewerUrl(
{
processId,
embeddedMode: true,
timestamp,
},
selectedVersionId!,
);
if (isUserErrorResponse(url)) return url;

const accessUpdateResult = await updateProcessGuestAccessRights(
processId,
embeddedMode: true,
timestamp,
},
selectedVersionId || undefined,
);
setEmbeddingUrl(url);
// activate embedding for that specific timestamp
await updateProcessGuestAccessRights(
processId,
{
sharedAs: 'public',
allowIframeTimestamp: timestamp,
},
environment.spaceId,
);
} catch (err) {
message.error('An error occured while enabling embedding.');
}
{
sharedAs: 'public',
allowIframeTimestamp: timestamp,
},
environment.spaceId,
);
if (isUserErrorResponse(accessUpdateResult)) return accessUpdateResult;

return url;
},
onSuccess: (url) => setEmbeddingUrl(url),
app,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

});
} else {
// deactivate embedding
try {
await updateProcessGuestAccessRights(
processId,
{ allowIframeTimestamp: 0 },
environment.spaceId,
);
setEmbeddingUrl('');
} catch (err) {
message.error('An error occured while disabling embedding.');
}
await wrapServerCall({
fn: () =>
updateProcessGuestAccessRights(
processId,
{ allowIframeTimestamp: 0 },
environment.spaceId,
),
onSuccess: () => setEmbeddingUrl(''),
app,
});
Comment on lines +97 to +106
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here

}
refresh();
};
Expand All @@ -104,8 +115,22 @@ const ModelerShareModalOptionEmdedInWeb = ({
message.success('Code copied to you clipboard');
};

if (processVersions.length === 0)
return (
<Result
status="warning"
title="No Process Versions"
subTitle="You can only embed process versions"
/>
);

return (
<>
<Space direction="vertical" style={{ width: '100%' }}>
<Select
defaultValue={selectedVersionId}
options={processVersions.map((version) => ({ value: version.id, label: version.name }))}
onChange={(value) => setSelectedVersionId(value)}
/>
<Checkbox
checked={embeddingUrl.length > 0 && allowIframeTimestamp > 0}
onChange={(e) => handleAllowEmbeddingChecked(e)}
Expand All @@ -123,11 +148,16 @@ const ModelerShareModalOptionEmdedInWeb = ({
/>
</div>
<div className="code">
<TextArea rows={2} value={iframeCode} style={{ backgroundColor: 'rgb(245,245,245)' }} />
<TextArea
rows={2}
value={iframeCode}
// @ts-expect-error fieldSizing works but isn't recognized as a valid field
style={{ backgroundColor: 'rgb(245,245,245)', fieldSizing: 'content' }}
/>
</div>
</>
) : null}
</>
</Space>
);
};

Expand Down
Loading