From 422556ce62781cff75e47611e39e450977af1009 Mon Sep 17 00:00:00 2001 From: Alexander Polyankin <alexander.polyankin@metabase.com> Date: Mon, 27 Jun 2022 15:40:42 +0300 Subject: [PATCH] Remove collection edit form (#23537) --- .../FormCollectionAuthorityLevel.jsx | 41 +----- .../metabase-enterprise/collections/index.js | 4 - .../CollectionHeader/CollectionMenu.tsx | 6 - .../CollectionEdit/CollectionEdit.tsx | 92 -------------- .../CollectionEdit/CollectionEditForm.tsx | 54 -------- .../containers/CollectionEdit/index.ts | 1 - frontend/src/metabase/routes.jsx | 2 - .../collections/collections.cy.spec.js | 14 +-- .../personal-collections.cy.spec.js | 34 ++--- .../moderation-collection.cy.spec.js | 117 +++--------------- .../timelines-collection.cy.spec.js | 9 +- 11 files changed, 37 insertions(+), 337 deletions(-) delete mode 100644 frontend/src/metabase/collections/containers/CollectionEdit/CollectionEdit.tsx delete mode 100644 frontend/src/metabase/collections/containers/CollectionEdit/CollectionEditForm.tsx delete mode 100644 frontend/src/metabase/collections/containers/CollectionEdit/index.ts diff --git a/enterprise/frontend/src/metabase-enterprise/collections/components/FormCollectionAuthorityLevel.jsx b/enterprise/frontend/src/metabase-enterprise/collections/components/FormCollectionAuthorityLevel.jsx index e0692de7e7b..e5dcdb20446 100644 --- a/enterprise/frontend/src/metabase-enterprise/collections/components/FormCollectionAuthorityLevel.jsx +++ b/enterprise/frontend/src/metabase-enterprise/collections/components/FormCollectionAuthorityLevel.jsx @@ -1,15 +1,10 @@ import React from "react"; import PropTypes from "prop-types"; -import { t } from "ttag"; - -import CheckBox from "metabase/core/components/CheckBox"; import { - SegmentedControl, optionShape, + SegmentedControl, } from "metabase/components/SegmentedControl"; - -import { AUTHORITY_LEVELS } from "../constants"; -import { FormFieldRoot, Label } from "./FormCollectionAuthorityLevel.styled"; +import { FormFieldRoot } from "./FormCollectionAuthorityLevel.styled"; const propTypes = { field: PropTypes.shape({ @@ -18,25 +13,9 @@ const propTypes = { onChange: PropTypes.func.isRequired, }).isRequired, options: PropTypes.arrayOf(optionShape).isRequired, - values: PropTypes.shape({ - id: PropTypes.number, - authority_level: PropTypes.oneOf(["official"]), - update_collection_tree_authority_level: PropTypes.bool, - }), - onChangeField: PropTypes.func.isRequired, }; -export function FormCollectionAuthorityLevel({ - field, - options, - values, - onChangeField, -}) { - const isNewCollection = !values.id; - const selectedAuthorityLevel = - AUTHORITY_LEVELS[field.value] || AUTHORITY_LEVELS.regular; - const shouldSuggestToUpdateChildren = - !isNewCollection && field.initialValue !== field.value; +export function FormCollectionAuthorityLevel({ field, options }) { return ( <FormFieldRoot> <SegmentedControl @@ -46,20 +25,6 @@ export function FormCollectionAuthorityLevel({ variant="fill-background" inactiveColor="text-dark" /> - {shouldSuggestToUpdateChildren && ( - <CheckBox - label={ - <Label>{t`Make all sub-collections ${selectedAuthorityLevel.name}, too.`}</Label> - } - checked={values.update_collection_tree_authority_level} - onChange={e => - onChangeField( - "update_collection_tree_authority_level", - e.target.checked, - ) - } - /> - )} </FormFieldRoot> ); } diff --git a/enterprise/frontend/src/metabase-enterprise/collections/index.js b/enterprise/frontend/src/metabase-enterprise/collections/index.js index cac6de3f015..d22ddbcdb88 100644 --- a/enterprise/frontend/src/metabase-enterprise/collections/index.js +++ b/enterprise/frontend/src/metabase-enterprise/collections/index.js @@ -65,10 +65,6 @@ PLUGIN_COLLECTIONS.getAuthorityLevelFormFields = () => [ }, ], }, - { - name: "update_collection_tree_authority_level", - type: "hidden", - }, ]; PLUGIN_FORM_WIDGETS.collectionAuthorityLevel = FormCollectionAuthorityLevel; diff --git a/frontend/src/metabase/collections/components/CollectionHeader/CollectionMenu.tsx b/frontend/src/metabase/collections/components/CollectionHeader/CollectionMenu.tsx index 950f83dc198..7d49096d0c1 100644 --- a/frontend/src/metabase/collections/components/CollectionHeader/CollectionMenu.tsx +++ b/frontend/src/metabase/collections/components/CollectionHeader/CollectionMenu.tsx @@ -49,12 +49,6 @@ const CollectionMenu = ({ if (!isRoot && !isPersonal && canWrite) { items.push( - { - title: t`Edit this collection`, - icon: "edit_document", - link: `${url}/edit`, - event: `${ANALYTICS_CONTEXT};Edit Menu;Edit Collection Click`, - }, { title: t`Move`, icon: "move", diff --git a/frontend/src/metabase/collections/containers/CollectionEdit/CollectionEdit.tsx b/frontend/src/metabase/collections/containers/CollectionEdit/CollectionEdit.tsx deleted file mode 100644 index f2cf96dc4ee..00000000000 --- a/frontend/src/metabase/collections/containers/CollectionEdit/CollectionEdit.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import React, { useCallback, useEffect, useState } from "react"; -import { connect } from "react-redux"; -import { goBack, push, LocationAction } from "react-router-redux"; -import _ from "underscore"; - -import * as Urls from "metabase/lib/urls"; -import Collections from "metabase/entities/collections"; - -import { Collection as BaseCollection, CollectionId } from "metabase-types/api"; -import { State } from "metabase-types/store"; - -import CollectionEditForm from "./CollectionEditForm"; - -type Collection = BaseCollection & { - parent_id: CollectionId; -}; - -interface CollectionEditOwnProps { - params: { - slug: string; - }; -} - -interface CollectionEditLoaderProps { - collection: Collection; -} - -interface CollectionEditDispatchProps { - push: LocationAction; - goBack: () => void; -} - -interface CollectionEditProps - extends CollectionEditOwnProps, - CollectionEditLoaderProps, - CollectionEditDispatchProps {} - -const mapDispatchToProps = { - push, - goBack, -}; - -function CollectionEdit({ collection, push, goBack }: CollectionEditProps) { - const [parentCollectionId, setParentCollectionId] = useState<CollectionId>( - collection?.parent_id, - ); - const [hasSetParentCollection, setHasSetParentCollection] = useState(false); - - useEffect(() => { - if (collection && !hasSetParentCollection) { - setParentCollectionId(collection.parent_id); - } - }, [collection, hasSetParentCollection]); - - const onChangeValues = useCallback( - (collection: Collection) => { - if (collection.parent_id !== parentCollectionId) { - setParentCollectionId(collection.parent_id); - setHasSetParentCollection(true); - } - }, - [parentCollectionId], - ); - - const onSave = useCallback( - collection => { - push(Urls.collection(collection)); - }, - [push], - ); - - return ( - <CollectionEditForm - collection={collection} - parentCollectionId={parentCollectionId} - onChange={onChangeValues} - onSave={onSave} - onClose={goBack} - /> - ); -} - -export default _.compose( - connect<unknown, CollectionEditDispatchProps, CollectionEditOwnProps, State>( - null, - mapDispatchToProps, - ), - Collections.load({ - id: (state: State, props: CollectionEditOwnProps) => - Urls.extractCollectionId(props.params.slug), - }), -)(CollectionEdit); diff --git a/frontend/src/metabase/collections/containers/CollectionEdit/CollectionEditForm.tsx b/frontend/src/metabase/collections/containers/CollectionEdit/CollectionEditForm.tsx deleted file mode 100644 index 21a60833c70..00000000000 --- a/frontend/src/metabase/collections/containers/CollectionEdit/CollectionEditForm.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; - -import Collections from "metabase/entities/collections"; - -import { Collection as BaseCollection, CollectionId } from "metabase-types/api"; -import { State } from "metabase-types/store"; - -type Collection = BaseCollection & { - parent_id: CollectionId; -}; - -interface CollectionEditFormOwnProps { - collection: Collection; - parentCollectionId: CollectionId; - onChange: (collection: Collection) => void; - onSave: (collection: Collection) => void; - onClose: () => void; -} - -interface CollectionEditFormStateProps { - form: unknown; -} - -interface CollectionEditProps - extends CollectionEditFormOwnProps, - CollectionEditFormStateProps {} - -function mapStateToProps(state: State, props: CollectionEditFormOwnProps) { - return { - form: Collections.selectors.getForm(state, props), - }; -} - -function CollectionEditForm({ - form, - collection, - onChange, - onSave, - onClose, -}: CollectionEditProps) { - return ( - <Collections.ModalForm - form={form} - collection={collection} - overwriteOnInitialValuesChange - onChange={onChange} - onSaved={onSave} - onClose={onClose} - /> - ); -} - -export default connect(mapStateToProps)(CollectionEditForm); diff --git a/frontend/src/metabase/collections/containers/CollectionEdit/index.ts b/frontend/src/metabase/collections/containers/CollectionEdit/index.ts deleted file mode 100644 index b7bebb0cfa4..00000000000 --- a/frontend/src/metabase/collections/containers/CollectionEdit/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./CollectionEdit"; diff --git a/frontend/src/metabase/routes.jsx b/frontend/src/metabase/routes.jsx index a269409668d..598f28a73f8 100644 --- a/frontend/src/metabase/routes.jsx +++ b/frontend/src/metabase/routes.jsx @@ -33,7 +33,6 @@ import TableBrowser from "metabase/browse/containers/TableBrowser"; import QueryBuilder from "metabase/query_builder/containers/QueryBuilder"; -import CollectionEdit from "metabase/collections/containers/CollectionEdit"; import CollectionCreate from "metabase/collections/containers/CollectionCreate"; import MoveCollectionModal from "metabase/collections/containers/MoveCollectionModal"; import ArchiveCollectionModal from "metabase/components/ArchiveCollectionModal"; @@ -218,7 +217,6 @@ export const getRoutes = store => ( </Route> <Route path="collection/:slug" component={CollectionLanding}> - <ModalRoute path="edit" modal={CollectionEdit} /> <ModalRoute path="move" modal={MoveCollectionModal} /> <ModalRoute path="archive" modal={ArchiveCollectionModal} /> <ModalRoute path="new_collection" modal={CollectionCreate} /> diff --git a/frontend/test/metabase/scenarios/collections/collections.cy.spec.js b/frontend/test/metabase/scenarios/collections/collections.cy.spec.js index 520735f48a0..a52b591aa0b 100644 --- a/frontend/test/metabase/scenarios/collections/collections.cy.spec.js +++ b/frontend/test/metabase/scenarios/collections/collections.cy.spec.js @@ -473,23 +473,15 @@ function ensureCollectionIsExpanded(collection, { children = [] } = {}) { function moveOpenedCollectionTo(newParent) { openCollectionMenu(); - cy.findByTextEnsureVisible("Edit this collection").click(); - - // Open the select dropdown menu - modal() - .findByTestId("select-button") - .click(); + popover().within(() => cy.findByText("Move").click()); cy.findAllByTestId("item-picker-item") .contains(newParent) .click(); - // Make sure the correct value is selected - cy.findAllByTestId("select-button-content").contains(newParent); - - cy.button("Update").click(); + cy.button("Move").click(); // Make sure modal closed - cy.button("Update").should("not.exist"); + cy.button("Move").should("not.exist"); } function dragAndDrop(subjectAlias, targetAlias) { diff --git a/frontend/test/metabase/scenarios/collections/personal-collections.cy.spec.js b/frontend/test/metabase/scenarios/collections/personal-collections.cy.spec.js index 0b2e02866ed..d6ed2768d9c 100644 --- a/frontend/test/metabase/scenarios/collections/personal-collections.cy.spec.js +++ b/frontend/test/metabase/scenarios/collections/personal-collections.cy.spec.js @@ -76,9 +76,9 @@ describe("personal collections", () => { .click(); // It should be possible to edit sub-collections' details, but not its permissions + cy.findByDisplayValue("Foo").should("be.enabled"); openCollectionMenu(); popover().within(() => { - cy.findByText("Edit this collection").should("be.visible"); cy.findByText("Edit permissions").should("not.exist"); }); @@ -130,31 +130,13 @@ describe("personal collections", () => { cy.get("@sidebar") .findByText("Bar") .click(); - openCollectionMenu(); - /** - * We're testing a few things here: - * 1. editing collection's title - * 2. editing collection's description and - * 3. moving that collection within personal collection - * 4. archiving the collection within personal collection (metabase#15343) - */ - popover().within(() => cy.findByText("Edit this collection").click()); - modal().within(() => { - cy.findByLabelText("Name") /* [1] */ - .click() - .type("1"); - - cy.findByLabelText("Description") /* [2] */ - .click() - .type("ex-bar", { delay: 0 }); - cy.findByTestId("select-button").click(); - }); - popover() - .findByText("My personal collection") /* [3] */ - .click(); - cy.button("Update").click(); - // Clicking on "Foo" would've closed it and would hide its sub-collections (if there were any). - // By doing this, we're making sure "Bar" lives at the same level as "Foo" + cy.findByPlaceholderText("Add title") + .type("1") + .blur(); + cy.findByPlaceholderText("Add description") + .type("ex-bar") + .blur(); + cy.get("@sidebar") .findByText("Foo") .click(); diff --git a/frontend/test/metabase/scenarios/organization/moderation-collection.cy.spec.js b/frontend/test/metabase/scenarios/organization/moderation-collection.cy.spec.js index bf09ea43f3e..de787509fd2 100644 --- a/frontend/test/metabase/scenarios/organization/moderation-collection.cy.spec.js +++ b/frontend/test/metabase/scenarios/organization/moderation-collection.cy.spec.js @@ -8,6 +8,8 @@ import { navigationSidebar, closeNavigationSidebar, getCollectionActions, + popover, + openCollectionMenu, } from "__support__/e2e/helpers"; import { SAMPLE_DATABASE } from "__support__/e2e/cypress_sample_database"; @@ -27,10 +29,6 @@ describeEE("collections types", () => { restore(); }); - const TREE_UPDATE_REGULAR_MESSAGE = "Make all sub-collections Regular, too."; - const TREE_UPDATE_OFFICIAL_MESSAGE = - "Make all sub-collections Official, too."; - it("should be able to manage collection authority level", () => { cy.signInAsAdmin(); cy.visit("/collection/root"); @@ -58,56 +56,6 @@ describeEE("collections types", () => { testOfficialQuestionBadgeInRegularDashboard(); }); - it("should be able to update authority level for collection children", () => { - cy.signInAsAdmin(); - cy.visit("/collection/root"); - cy.findByText("First collection").click(); - - // Test not visible when creating a new collection - openNewCollectionItemFlowFor("collection"); - modal().within(() => { - cy.findByText(TREE_UPDATE_REGULAR_MESSAGE).should("not.exist"); - cy.findByText(TREE_UPDATE_OFFICIAL_MESSAGE).should("not.exist"); - setOfficial(); - cy.findByText(TREE_UPDATE_REGULAR_MESSAGE).should("not.exist"); - cy.findByText(TREE_UPDATE_OFFICIAL_MESSAGE).should("not.exist"); - cy.icon("close").click(); - }); - - // Test can make all children official - editCollection(); - modal().within(() => { - cy.findByText(TREE_UPDATE_REGULAR_MESSAGE).should("not.exist"); - cy.findByText(TREE_UPDATE_OFFICIAL_MESSAGE).should("not.exist"); - setOfficial(); - cy.findByText(TREE_UPDATE_REGULAR_MESSAGE).should("not.exist"); - cy.findByText(TREE_UPDATE_OFFICIAL_MESSAGE).click(); - cy.button("Update").click(); - }); - - getSidebarCollectionChildrenFor("First collection").within(() => { - expandCollectionChildren("Second collection"); - cy.icon("badge").should("have.length", 2); - cy.icon("folder").should("not.exist"); - }); - - // Test can make all children regular - editCollection(); - modal().within(() => { - cy.findByText(TREE_UPDATE_REGULAR_MESSAGE).should("not.exist"); - cy.findByText(TREE_UPDATE_OFFICIAL_MESSAGE).should("not.exist"); - setOfficial(false); - cy.findByText(TREE_UPDATE_REGULAR_MESSAGE).click(); - cy.findByText(TREE_UPDATE_OFFICIAL_MESSAGE).should("not.exist"); - cy.button("Update").click(); - }); - - getSidebarCollectionChildrenFor("First collection").within(() => { - cy.icon("folder").should("have.length", 2); - cy.icon("badge").should("not.exist"); - }); - }); - it("should not see collection type field if not admin", () => { cy.signIn("normal"); cy.visit("/collection/root"); @@ -120,9 +68,9 @@ describeEE("collections types", () => { cy.icon("close").click(); }); - editCollection(); - modal().within(() => { - assertNoCollectionTypeInput(); + openCollectionMenu(); + popover().within(() => { + assertNoCollectionTypeOption(); }); }); @@ -170,10 +118,8 @@ describe("collection types", { tags: "@OSS" }, () => { }); openCollection("First collection"); - editCollection(); - modal().within(() => { - assertNoCollectionTypeInput(); - }); + openCollectionMenu(); + assertNoCollectionTypeOption(); }); it("should not display official collection icon", () => { @@ -279,42 +225,11 @@ function openCollection(collectionName) { .click(); } -function editCollection() { - cy.findByTestId("collection-menu").within(() => cy.icon("ellipsis").click()); - cy.findByText("Edit this collection").click(); -} - -function expandCollectionChildren(collectionName) { - cy.findByText(collectionName) - .parentsUntil("[data-testid=sidebar-collection-link-root]") - .find(".Icon-chevronright") - .click(); -} - -function getSidebarCollectionChildrenFor(item) { - return navigationSidebar() - .findByText(item) - .parentsUntil("[data-testid=sidebar-collection-link-root]") - .parent() - .next("ul"); -} - -function setOfficial(official = true) { - const isOfficialNow = !official; - cy.findByLabelText("Regular").should( - isOfficialNow ? "not.be.checked" : "be.checked", - ); - cy.findByLabelText("Official").should( - isOfficialNow ? "be.checked" : "not.be.checked", - ); - cy.findByText(official ? "Official" : "Regular").click(); -} - function createAndOpenOfficialCollection({ name }) { openNewCollectionItemFlowFor("collection"); modal().within(() => { cy.findByLabelText("Name").type(name); - setOfficial(); + cy.findByText("Official").click(); cy.button("Create").click(); }); navigationSidebar().within(() => { @@ -323,10 +238,13 @@ function createAndOpenOfficialCollection({ name }) { } function changeCollectionTypeTo(type) { - editCollection(); - modal().within(() => { - setOfficial(type === "official"); - cy.button("Update").click(); + openCollectionMenu(); + popover().within(() => { + if (type === "official") { + cy.findByText("Make collection official").click(); + } else { + cy.findByText("Make collection unofficial").click(); + } }); } @@ -336,6 +254,11 @@ function assertNoCollectionTypeInput() { cy.findByText("Official").should("not.exist"); } +function assertNoCollectionTypeOption() { + cy.findByText("Make collection official").should("not.exist"); + cy.findByText("Make collection unofficial").should("not.exist"); +} + function assertSidebarIcon(collectionName, expectedIcon) { navigationSidebar() .findByText(collectionName) diff --git a/frontend/test/metabase/scenarios/organization/timelines-collection.cy.spec.js b/frontend/test/metabase/scenarios/organization/timelines-collection.cy.spec.js index 89dbda156dd..99345279692 100644 --- a/frontend/test/metabase/scenarios/organization/timelines-collection.cy.spec.js +++ b/frontend/test/metabase/scenarios/organization/timelines-collection.cy.spec.js @@ -3,7 +3,6 @@ import { enableTracking, expectGoodSnowplowEvents, expectNoBadSnowplowEvents, - openCollectionMenu, resetSnowplow, restore, } from "__support__/e2e/helpers"; @@ -493,12 +492,10 @@ describe("scenarios > organization > timelines > collection", () => { cy.wait("@createTimeline"); cy.icon("close").click(); - openCollectionMenu(); - cy.findByText("Edit this collection").click(); - cy.findByLabelText("Name") + cy.findByDisplayValue("First collection") .clear() - .type("1st collection"); - cy.button("Update").click(); + .type("1st collection") + .blur(); cy.wait("@updateCollection"); cy.icon("calendar").click(); -- GitLab