| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- import React, {
- useState, useMemo, useCallback,
- } from 'react';
- import { pagePathUtils } from '@growi/core';
- import { useTranslation } from 'next-i18next';
- import PropTypes from 'prop-types';
- import { CopyToClipboard } from 'react-copy-to-clipboard';
- import {
- Dropdown, DropdownToggle, DropdownMenu, DropdownItem,
- Tooltip,
- } from 'reactstrap';
- import styles from './CopyDropdown.module.scss';
- const { encodeSpaces } = pagePathUtils;
- /* eslint-disable react/prop-types */
- const DropdownItemContents = ({ title, contents }) => (
- <>
- <div className="h6 mt-1 mb-2"><strong>{title}</strong></div>
- <div className="card well mb-1 p-2">{contents}</div>
- </>
- );
- /* eslint-enable react/prop-types */
- const CopyDropdown = (props) => {
- const [dropdownOpen, setDropdownOpen] = useState(false);
- const [tooltipOpen, setTooltipOpen] = useState(false);
- const [isParamsAppended, setParamsAppended] = useState(!props.isShareLinkMode);
- /*
- * functions to construct labels and URLs
- */
- const getUriParams = useCallback(() => {
- if (!isParamsAppended || !dropdownOpen) {
- return '';
- }
- const {
- search, hash,
- } = window.location;
- return `${search}${hash}`;
- }, [isParamsAppended, dropdownOpen]);
- const pagePathWithParams = useMemo(() => {
- const { pagePath } = props;
- return decodeURI(`${pagePath}${getUriParams()}`);
- }, [props, getUriParams]);
- const pagePathUrl = useMemo(() => {
- const { origin } = window.location;
- return `${origin}${encodeSpaces(pagePathWithParams)}`;
- }, [pagePathWithParams]);
- const permalink = useMemo(() => {
- const { origin } = window.location;
- const { pageId, isShareLinkMode } = props;
- if (pageId == null) {
- return null;
- }
- if (isShareLinkMode) {
- return decodeURI(`${origin}/share/${pageId}`);
- }
- return encodeSpaces(decodeURI(`${origin}/${pageId}${getUriParams()}`));
- }, [props, getUriParams]);
- const markdownLink = useMemo(() => {
- const { pagePath } = props;
- const label = decodeURI(`${pagePath}${getUriParams()}`);
- // const permalink = generatePermalink();
- return `[${label}](${permalink})`;
- }, [props, getUriParams, permalink]);
- /**
- * control
- */
- const toggleDropdown = useCallback(() => {
- setDropdownOpen(!dropdownOpen);
- }, [dropdownOpen]);
- const toggleAppendParams = useCallback(() => {
- setParamsAppended(!isParamsAppended);
- }, [isParamsAppended]);
- const showToolTip = useCallback(() => {
- setTooltipOpen(true);
- setTimeout(() => {
- setTooltipOpen(false);
- }, 1000);
- }, []);
- /*
- * render
- */
- const { t } = useTranslation('commons');
- const {
- dropdownToggleId, pageId, dropdownToggleClassName, children, isShareLinkMode,
- } = props;
- const customSwitchForParamsId = `customSwitchForParams_${dropdownToggleId}`;
- return (
- <>
- <Dropdown className={`${styles['grw-copy-dropdown']} grw-copy-dropdown`} isOpen={dropdownOpen} toggle={toggleDropdown}>
- <DropdownToggle
- caret
- className={dropdownToggleClassName}
- >
- <span id={dropdownToggleId}>{children}</span>
- </DropdownToggle>
- <DropdownMenu positionFixed modifiers={{ preventOverflow: { boundariesElement: 'viewport' } }}>
- <div className="d-flex align-items-center justify-content-between">
- <DropdownItem header className="px-3">
- { t('copy_to_clipboard.Copy to clipboard') }
- </DropdownItem>
- { !isShareLinkMode && (
- <div className="px-3 custom-control custom-switch custom-switch-sm">
- <input
- type="checkbox"
- id={customSwitchForParamsId}
- className="custom-control-input"
- checked={isParamsAppended}
- onChange={toggleAppendParams}
- />
- <label className="custom-control-label small" htmlFor={customSwitchForParamsId}>Append params</label>
- </div>
- ) }
- </div>
- <DropdownItem divider className="my-0"></DropdownItem>
- {/* Page path */}
- <CopyToClipboard text={pagePathWithParams} onCopy={showToolTip}>
- <DropdownItem className="px-3">
- <DropdownItemContents title={t('copy_to_clipboard.Page path')} contents={pagePathWithParams} />
- </DropdownItem>
- </CopyToClipboard>
- <DropdownItem divider className="my-0"></DropdownItem>
- {/* Page path URL */}
- <CopyToClipboard text={pagePathUrl} onCopy={showToolTip}>
- <DropdownItem className="px-3">
- <DropdownItemContents title={t('copy_to_clipboard.Page URL')} contents={pagePathUrl} />
- </DropdownItem>
- </CopyToClipboard>
- <DropdownItem divider className="my-0"></DropdownItem>
- {/* Permanent Link */}
- { pageId && (
- <CopyToClipboard text={permalink} onCopy={showToolTip}>
- <DropdownItem className="px-3">
- <DropdownItemContents title={t('copy_to_clipboard.Permanent link')} contents={permalink} />
- </DropdownItem>
- </CopyToClipboard>
- )}
- <DropdownItem divider className="my-0"></DropdownItem>
- {/* Page path + Permanent Link */}
- { pageId && (
- <CopyToClipboard text={`${pagePathWithParams}\n${permalink}`} onCopy={showToolTip}>
- <DropdownItem className="px-3">
- <DropdownItemContents
- title={t('copy_to_clipboard.Page path and permanent link')}
- contents={<>{pagePathWithParams}<br />{permalink}</>}
- />
- </DropdownItem>
- </CopyToClipboard>
- )}
- <DropdownItem divider className="my-0"></DropdownItem>
- {/* Markdown Link */}
- { pageId && (
- <CopyToClipboard text={markdownLink} onCopy={showToolTip}>
- <DropdownItem className="px-3 text-wrap">
- <DropdownItemContents title={t('copy_to_clipboard.Markdown link')} contents={markdownLink} isContentsWrap />
- </DropdownItem>
- </CopyToClipboard>
- )}
- </DropdownMenu>
- </Dropdown>
- <Tooltip placement="bottom" isOpen={tooltipOpen} target={dropdownToggleId} fade={false}>
- copied!
- </Tooltip>
- </>
- );
- };
- CopyDropdown.propTypes = {
- children: PropTypes.node.isRequired,
- dropdownToggleId: PropTypes.string.isRequired,
- pagePath: PropTypes.string.isRequired,
- pageId: PropTypes.string,
- dropdownToggleClassName: PropTypes.string,
- isShareLinkMode: PropTypes.bool,
- };
- export default CopyDropdown;
|