diff --git a/client/app/bundles/course/assessment/submission/components/ReadOnlyEditor/index.jsx b/client/app/bundles/course/assessment/submission/components/ReadOnlyEditor/index.jsx
index e94e905f6f0..8ce262a9b86 100644
--- a/client/app/bundles/course/assessment/submission/components/ReadOnlyEditor/index.jsx
+++ b/client/app/bundles/course/assessment/submission/components/ReadOnlyEditor/index.jsx
@@ -5,6 +5,7 @@ import PropTypes from 'prop-types';
import { annotationShape, fileShape } from '../../propTypes';
import translations from '../../translations';
+import CopyCodeButton from '../answers/Programming/CopyCodeButton';
import ProgrammingFileDownloadChip from '../answers/Programming/ProgrammingFileDownloadChip';
import NarrowEditor from './NarrowEditor';
@@ -212,7 +213,10 @@ class ReadOnlyEditor extends Component {
return (
<>
-
+
{this.renderShowCommentsPanel()}
{this.renderExpandAllToggle()}
diff --git a/client/app/bundles/course/assessment/submission/components/answers/Programming/CopyCodeButton.tsx b/client/app/bundles/course/assessment/submission/components/answers/Programming/CopyCodeButton.tsx
new file mode 100644
index 00000000000..df396308f98
--- /dev/null
+++ b/client/app/bundles/course/assessment/submission/components/answers/Programming/CopyCodeButton.tsx
@@ -0,0 +1,33 @@
+import { FC } from 'react';
+import { ContentCopy } from '@mui/icons-material';
+import { Chip } from '@mui/material';
+import { ProgrammingContent } from 'types/course/assessment/submission/answer/programming';
+
+import toast from 'lib/hooks/toast';
+
+interface Props {
+ file: ProgrammingContent;
+}
+
+const CopyCodeButton: FC
= (props) => {
+ const { file } = props;
+
+ const handleCopy = (): void => {
+ navigator.clipboard.writeText(file.content).then(() => {
+ toast.success('Copied to clipboard');
+ });
+ };
+
+ return (
+ }
+ label="Copy"
+ onClick={handleCopy}
+ size="small"
+ variant="outlined"
+ />
+ );
+};
+
+export default CopyCodeButton;