import React, { useCallback, useState } from 'react';
import {
PageGrant, isPopulated, GroupType, type IGrantedGroup,
} from '@growi/core';
import { LoadingSpinner } from '@growi/ui/dist/components';
import { useTranslation } from 'next-i18next';
import {
UncontrolledDropdown,
DropdownToggle, DropdownMenu, DropdownItem,
Modal, ModalHeader, ModalBody,
} from 'reactstrap';
import type { IPageGrantData } from '~/interfaces/page';
import { useCurrentUser } from '~/stores/context';
import { useMyUserGroups } from './use-my-user-groups';
const AVAILABLE_GRANTS = [
{
grant: PageGrant.GRANT_PUBLIC, iconName: 'group', btnStyleClass: 'outline-info', label: 'Public',
},
{
grant: PageGrant.GRANT_RESTRICTED, iconName: 'link', btnStyleClass: 'outline-success', label: 'Anyone with the link',
},
// { grant: 3, iconClass: '', label: 'Specified users only' },
{
grant: PageGrant.GRANT_OWNER, iconName: 'lock', btnStyleClass: 'outline-danger', label: 'Only me',
},
{
grant: PageGrant.GRANT_USER_GROUP,
iconName: 'more_horiz',
btnStyleClass: 'outline-warning',
label: 'Only inside the group',
reselectLabel: 'Reselect the group',
},
];
type Props = {
disabled?: boolean,
openInModal?: boolean,
grant: PageGrant,
userRelatedGrantedGroups?: {
id: string,
name: string,
type: GroupType,
}[]
onUpdateGrant?: (grantData: IPageGrantData) => void,
}
/**
* Page grant select component
*/
export const GrantSelector = (props: Props): JSX.Element => {
const { t } = useTranslation();
const {
disabled,
openInModal,
userRelatedGrantedGroups,
onUpdateGrant,
grant: currentGrant,
} = props;
const [isSelectGroupModalShown, setIsSelectGroupModalShown] = useState(false);
const { data: currentUser } = useCurrentUser();
const shouldFetch = isSelectGroupModalShown;
const { data: myUserGroups, update: updateMyUserGroups } = useMyUserGroups(shouldFetch);
const showSelectGroupModal = useCallback(() => {
updateMyUserGroups();
setIsSelectGroupModalShown(true);
}, [updateMyUserGroups]);
/**
* change event handler for grant selector
*/
const changeGrantHandler = useCallback((grant: PageGrant) => {
// select group
if (grant === 5) {
showSelectGroupModal();
return;
}
if (onUpdateGrant != null) {
onUpdateGrant({ grant, userRelatedGrantedGroups: undefined });
}
}, [onUpdateGrant, showSelectGroupModal]);
const groupListItemClickHandler = useCallback((grantGroup: IGrantedGroup) => {
if (onUpdateGrant != null && isPopulated(grantGroup.item)) {
let userRelatedGrantedGroupsCopy = userRelatedGrantedGroups != null ? [...userRelatedGrantedGroups] : [];
const grantGroupInfo = { id: grantGroup.item._id, name: grantGroup.item.name, type: grantGroup.type };
if (userRelatedGrantedGroupsCopy.find(group => group.id === grantGroupInfo.id) == null) {
userRelatedGrantedGroupsCopy.push(grantGroupInfo);
}
else {
userRelatedGrantedGroupsCopy = userRelatedGrantedGroupsCopy.filter(group => group.id !== grantGroupInfo.id);
}
onUpdateGrant({ grant: 5, userRelatedGrantedGroups: userRelatedGrantedGroupsCopy });
}
}, [onUpdateGrant, userRelatedGrantedGroups]);
/**
* Render grant selector DOM.
*/
const renderGrantSelector = useCallback(() => {
let dropdownToggleBtnColor;
let dropdownToggleLabelElm;
const dropdownMenuElems = AVAILABLE_GRANTS.map((opt) => {
const label = ((opt.grant === 5 && opt.reselectLabel != null) && userRelatedGrantedGroups != null && userRelatedGrantedGroups.length > 0)
? opt.reselectLabel // when grantGroup is selected
: opt.label;
const labelElm = (
{opt.iconName}
{t(label)}
);
// set dropdownToggleBtnColor, dropdownToggleLabelElm
if (opt.grant === 1 || opt.grant === currentGrant) {
dropdownToggleBtnColor = opt.btnStyleClass;
dropdownToggleLabelElm = labelElm;
}
return