Skip to content

Commit df90eec

Browse files
committed
feat: Enable copy menus in unit info sidebar
1 parent adb5295 commit df90eec

2 files changed

Lines changed: 26 additions & 3 deletions

File tree

src/course-outline/outline-sidebar/info-sidebar/UnitInfoSidebar.tsx

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { useOutlineSidebarContext } from '../OutlineSidebarContext';
2525
import { PublishButon } from './PublishButon';
2626
import messages from '../messages';
2727
import { InfoSection } from './InfoSection';
28+
import { useClipboard } from '@src/generic/clipboard';
2829

2930
export const UnitSidebar = () => {
3031
const intl = useIntl();
@@ -46,6 +47,7 @@ export const UnitSidebar = () => {
4647
openDeleteModal,
4748
openUnlinkModal,
4849
} = useCourseAuthoringContext();
50+
const { copyToClipboard } = useClipboard();
4951

5052
const handlePublish = () => {
5153
if (unitData?.hasChanges) {
@@ -118,6 +120,27 @@ export const UnitSidebar = () => {
118120
}
119121
};
120122

123+
const handleCopyLocation = () => {
124+
// Extract the location ID: the part after "block@" at the end of the usage key
125+
// e.g. "block-v1:org+course+run+type@vertical+block@abc123" → "abc123"
126+
const locationId = unitId.match(/block@(.+)$/)?.[1];
127+
if (!locationId) { return; }
128+
129+
if (navigator.clipboard) {
130+
// Modern approach: requires HTTPS (secure context)
131+
void navigator.clipboard.writeText(locationId);
132+
} else {
133+
// Fallback for HTTP (non-secure) dev environments
134+
// Note: execCommand is deprecated but still widely supported as fallback
135+
const textarea = document.createElement('textarea');
136+
textarea.value = locationId;
137+
document.body.appendChild(textarea);
138+
textarea.select();
139+
document.execCommand('copy'); // eslint-disable-line deprecation/deprecation
140+
document.body.removeChild(textarea);
141+
}
142+
};
143+
121144
return (
122145
<>
123146
<SidebarTitle
@@ -144,8 +167,8 @@ export const UnitSidebar = () => {
144167
navigate(`/library/${libId}/unit/${upstreamRef}`);
145168
}
146169
},
147-
onClickCopy: () => {},
148-
onClickCopyLocation: () => {},
170+
onClickCopy: () => copyToClipboard(unitId),
171+
onClickCopyLocation: handleCopyLocation,
149172
}}
150173
/>
151174
<Stack direction="horizontal" gap={1} className="mx-2">

src/generic/sidebar/InfoSidebarMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export const InfoSidebarMenu = ({
8484
<Dropdown.Item onClick={onClickCopyLocation}>
8585
<Stack direction="horizontal" gap={2}>
8686
<Icon src={ContentCopy} />
87-
{intl.formatMessage(messages.menuCopy)}
87+
{intl.formatMessage(messages.menuCopyLocation)}
8888
</Stack>
8989
</Dropdown.Item>
9090
)}

0 commit comments

Comments
 (0)