Skip to content
Snippets Groups Projects
Unverified Commit da76aaa0 authored by Alexander Polyankin's avatar Alexander Polyankin Committed by GitHub
Browse files

Make collections official via menu (#23535)

parent c191c47f
No related branches found
No related tags found
No related merge requests found
......@@ -19,7 +19,33 @@ PLUGIN_COLLECTIONS.REGULAR_COLLECTION = REGULAR_COLLECTION;
PLUGIN_COLLECTIONS.AUTHORITY_LEVEL = AUTHORITY_LEVELS;
PLUGIN_COLLECTIONS.authorityLevelFormFields = [
PLUGIN_COLLECTIONS.getAuthorityLevelMenuItems = (collection, onUpdate) => {
if (isRegularCollection(collection)) {
return [
{
title: t`Make collection official`,
icon: OFFICIAL_COLLECTION.icon,
action: () =>
onUpdate(collection, {
authority_level: OFFICIAL_COLLECTION.type,
}),
},
];
} else {
return [
{
title: t`Make collection unofficial`,
icon: REGULAR_COLLECTION.icon,
action: () =>
onUpdate(collection, {
authority_level: REGULAR_COLLECTION.type,
}),
},
];
}
};
PLUGIN_COLLECTIONS.getAuthorityLevelFormFields = () => [
{
name: "authority_level",
title: t`Collection type`,
......
......@@ -20,6 +20,10 @@ export const CaptionDescription = styled(EditableText)<CaptionDescriptionProps>`
opacity: ${props => (props.isVisible ? 1 : 0)};
max-width: 25rem;
transition: opacity 400ms ease 1s;
@media (prefers-reduced-motion) {
transition: none;
}
`;
export const CaptionRoot = styled.div`
......
......@@ -15,17 +15,12 @@ import {
export interface CollectionCaptionProps {
collection: Collection;
onChangeName: (collection: Collection, name: string) => void;
onChangeDescription: (
collection: Collection,
description: string | null,
) => void;
onUpdateCollection: (entity: Collection, values: Partial<Collection>) => void;
}
const CollectionCaption = ({
collection,
onChangeName,
onChangeDescription,
onUpdateCollection,
}: CollectionCaptionProps): JSX.Element => {
const isRoot = isRootCollection(collection);
const isPersonal = isPersonalCollection(collection);
......@@ -33,16 +28,16 @@ const CollectionCaption = ({
const handleChangeName = useCallback(
(name: string) => {
onChangeName(collection, name);
onUpdateCollection(collection, { name });
},
[collection, onChangeName],
[collection, onUpdateCollection],
);
const handleChangeDescription = useCallback(
(description: string) => {
onChangeDescription(collection, description ? description : null);
onUpdateCollection(collection, { description: description || null });
},
[collection, onChangeDescription],
[collection, onUpdateCollection],
);
return (
......
......@@ -11,11 +11,7 @@ export interface CollectionHeaderProps {
isAdmin: boolean;
isBookmarked: boolean;
isPersonalCollectionChild: boolean;
onChangeName: (collection: Collection, name: string) => void;
onChangeDescription: (
collection: Collection,
description: string | null,
) => void;
onUpdateCollection: (entity: Collection, values: Partial<Collection>) => void;
onCreateBookmark: (collection: Collection) => void;
onDeleteBookmark: (collection: Collection) => void;
}
......@@ -25,8 +21,7 @@ const CollectionHeader = ({
isAdmin,
isBookmarked,
isPersonalCollectionChild,
onChangeName,
onChangeDescription,
onUpdateCollection,
onCreateBookmark,
onDeleteBookmark,
}: CollectionHeaderProps): JSX.Element => {
......@@ -34,8 +29,7 @@ const CollectionHeader = ({
<HeaderRoot>
<CollectionCaption
collection={collection}
onChangeName={onChangeName}
onChangeDescription={onChangeDescription}
onUpdateCollection={onUpdateCollection}
/>
<HeaderActions data-testid="collection-menu">
<CollectionTimeline collection={collection} />
......@@ -49,6 +43,7 @@ const CollectionHeader = ({
collection={collection}
isAdmin={isAdmin}
isPersonalCollectionChild={isPersonalCollectionChild}
onUpdateCollection={onUpdateCollection}
/>
</HeaderActions>
</HeaderRoot>
......
import React from "react";
import { t } from "ttag";
import { PLUGIN_COLLECTIONS } from "metabase/plugins";
import * as Urls from "metabase/lib/urls";
import EntityMenu from "metabase/components/EntityMenu";
import { ANALYTICS_CONTEXT } from "metabase/collections/constants";
......@@ -13,12 +14,14 @@ export interface CollectionMenuProps {
collection: Collection;
isAdmin: boolean;
isPersonalCollectionChild: boolean;
onUpdateCollection: (entity: Collection, values: Partial<Collection>) => void;
}
const CollectionMenu = ({
collection,
isAdmin,
isPersonalCollectionChild,
onUpdateCollection,
}: CollectionMenuProps): JSX.Element | null => {
const items = [];
const url = Urls.collection(collection);
......@@ -26,6 +29,24 @@ const CollectionMenu = ({
const isPersonal = isPersonalCollection(collection);
const canWrite = collection.can_write;
if (isAdmin && !isRoot && !isPersonal && !isPersonalCollectionChild) {
items.push(
...PLUGIN_COLLECTIONS.getAuthorityLevelMenuItems(
collection,
onUpdateCollection,
),
);
}
if (isAdmin && !isPersonal && !isPersonalCollectionChild) {
items.push({
title: t`Edit permissions`,
icon: "lock",
link: `${url}/permissions`,
event: `${ANALYTICS_CONTEXT};Edit Menu;Edit Permissions`,
});
}
if (!isRoot && !isPersonal && canWrite) {
items.push(
{
......@@ -49,15 +70,6 @@ const CollectionMenu = ({
);
}
if (isAdmin && !isPersonal && !isPersonalCollectionChild) {
items.push({
title: t`Edit permissions`,
icon: "lock",
link: `${url}/permissions`,
event: `${ANALYTICS_CONTEXT};Edit Menu;Edit Permissions`,
});
}
if (items.length > 0) {
return <EntityMenu items={items} triggerIcon="ellipsis" />;
} else {
......
......@@ -4,10 +4,8 @@ import { Collection } from "metabase-types/api";
import CollectionHeader from "../../components/CollectionHeader";
const mapDispatchToProps = {
onChangeName: (collection: Collection, name: string) =>
Collections.actions.update(collection, { name }),
onChangeDescription: (collection: Collection, description: string | null) =>
Collections.actions.update(collection, { description }),
onUpdateCollection: (collection: Collection, values: Partial<Collection>) =>
Collections.actions.update(collection, values),
};
export default connect(null, mapDispatchToProps)(CollectionHeader);
......@@ -79,10 +79,9 @@ export const getFormSelector = createSelector(
!isPersonalOrPersonalChild(parentCollection, collectionList);
if (canManageAuthorityLevel) {
extraFields.push(...PLUGIN_COLLECTIONS.authorityLevelFormFields);
extraFields.push(...PLUGIN_COLLECTIONS.getAuthorityLevelFormFields());
}
const form = createForm({ extraFields });
return form;
return createForm({ extraFields });
},
);
......@@ -101,12 +101,16 @@ const AUTHORITY_LEVEL_REGULAR = {
};
export const PLUGIN_COLLECTIONS = {
authorityLevelFormFields: [],
isRegularCollection: (_: Collection | Bookmark) => true,
REGULAR_COLLECTION: AUTHORITY_LEVEL_REGULAR,
AUTHORITY_LEVEL: {
[JSON.stringify(AUTHORITY_LEVEL_REGULAR.type)]: AUTHORITY_LEVEL_REGULAR,
},
REGULAR_COLLECTION: AUTHORITY_LEVEL_REGULAR,
isRegularCollection: (_: Collection | Bookmark) => true,
getAuthorityLevelFormFields: () => [],
getAuthorityLevelMenuItems: (
_collection: Collection,
_onUpdate: (collection: Collection, values: Partial<Collection>) => void,
) => [],
};
export const PLUGIN_COLLECTION_COMPONENTS = {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment