From 4e86870caf94344977f4049c1aac0bac0a6d3454 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Thu, 16 Jul 2020 12:46:14 +0200 Subject: [PATCH 1/5] delete folder --- .../Components/Breadcrumbs/index.tsx | 0 .../Components/EmptyScreen/index.tsx | 0 .../Filters/FilterOptions/index.tsx | 0 .../Components/Filters/SortOptions/index.tsx | 0 .../Components/Filters/ViewOptions/icons.tsx | 0 .../Components/Filters/ViewOptions/index.tsx | 0 .../Components/Folder/CreateFolder.tsx | 0 .../Components/Folder/DragPreview.tsx | 0 .../Components/Folder/FolderCard.tsx | 0 .../Components/Folder/FolderListItem.tsx | 0 .../Components/Folder/index.tsx | 0 .../Components/Folder/types.ts | 0 .../Components/Header/index.tsx | 0 .../Components/Loading/index.tsx | 0 .../Components/Repo/Icons.tsx | 0 .../Components/Repo/ImportRepo.tsx | 0 .../Components/Repo/RepoCard.tsx | 0 .../Components/Repo/RepoListItem.tsx | 0 .../Components/Repo/index.tsx | 0 .../Components/Sandbox/NewMasterSandbox.tsx | 0 .../Components/Sandbox/NewSandbox.tsx | 0 .../Components/Sandbox/SandboxCard.tsx | 0 .../Components/Sandbox/SandboxListItem.tsx | 0 .../Components/Sandbox/TemplateIcon.tsx | 0 .../Components/Sandbox/index.tsx | 0 .../Components/Sandbox/types.ts | 0 .../Components/Selection/ContextMenu.tsx | 0 .../Selection/ContextMenus/ContainerMenu.tsx | 0 .../Selection/ContextMenus/FolderMenu.tsx | 0 .../Selection/ContextMenus/MasterMenu.tsx | 0 .../Selection/ContextMenus/MultiItemMenu.tsx | 0 .../Selection/ContextMenus/RepoMenu.tsx | 0 .../Selection/ContextMenus/SandboxMenu.tsx | 0 .../Selection/ContextMenus/index.ts | 0 .../Components/Selection/DragPreview.tsx | 0 .../Components/Selection/index.tsx | 0 .../Components/VariableGrid/index.tsx | 0 .../AnimatedSandboxItem.tsx | 104 --- .../SelectedSandboxItems/elements.ts | 30 - .../DragLayer/SelectedSandboxItems/index.tsx | 48 -- .../Dashboard/Content/DragLayer/index.js | 82 -- .../Content/SandboxCard/KebabIcon.tsx | 12 - .../Dashboard/Content/SandboxCard/elements.ts | 95 --- .../Dashboard/Content/SandboxCard/index.tsx | 697 ---------------- .../Dashboard/Content/SandboxGrid/Row.js | 64 -- .../Dashboard/Content/SandboxGrid/elements.js | 29 - .../Dashboard/Content/SandboxGrid/index.tsx | 543 ------------ .../Content/Sandboxes/Actions/elements.ts | 36 - .../Content/Sandboxes/Actions/index.tsx | 25 - .../Filters/FilterOptions/Option.tsx | 42 - .../Filters/FilterOptions/elements.ts | 115 --- .../Sandboxes/Filters/FilterOptions/index.tsx | 113 --- .../Filters/SortOptions/FieldToName.ts | 5 - .../SortOptions/Overlay/Option/elements.ts | 35 - .../SortOptions/Overlay/Option/index.tsx | 25 - .../Filters/SortOptions/Overlay/elements.ts | 21 - .../Filters/SortOptions/Overlay/index.tsx | 48 -- .../Sandboxes/Filters/SortOptions/elements.ts | 49 -- .../Sandboxes/Filters/SortOptions/index.tsx | 51 -- .../Content/Sandboxes/Filters/elements.ts | 13 - .../Content/Sandboxes/Filters/index.tsx | 26 - .../Dashboard/Content/Sandboxes/index.tsx | 98 --- .../Dashboard/Content/Sandboxes/utils.ts | 19 - .../Dashboard/Content/Selection/index.js | 35 - .../app/pages/Dashboard/Content/elements.js | 41 - .../src/app/pages/Dashboard/Content/index.js | 51 -- .../Content/index.tsx | 0 .../Content/routes/All/index.tsx | 0 .../Content/routes/All/useFilteredItems.ts | 0 .../routes/CreateTeam/Plan/elements.js | 71 -- .../Content/routes/CreateTeam/Plan/index.js | 30 - .../Content/routes/CreateTeam/elements.js | 57 -- .../Content/routes/CreateTeam/index.js | 168 ---- .../Content/routes/Deleted/index.tsx | 0 .../Content/routes/DeletedSandboxes/index.js | 76 -- .../Content/routes/Drafts/index.tsx | 0 .../Content/routes/Home/index.tsx | 0 .../Content/routes/PathedSandboxes/Folders.js | 54 -- .../Navigation/NavigationLink.tsx | 57 -- .../PathedSandboxes/Navigation/elements.ts | 46 - .../PathedSandboxes/Navigation/index.tsx | 44 - .../routes/PathedSandboxes/elements.js | 20 - .../Content/routes/PathedSandboxes/index.js | 93 --- .../Content/routes/Recent/index.tsx | 0 .../Content/routes/RecentSandboxes/index.tsx | 64 -- .../Content/routes/Repositories/index.tsx | 0 .../routes/Repositories/useFilteredItems.ts | 0 .../Content/routes/Search/index.tsx | 0 .../Content/routes/SearchSandboxes/index.js | 87 -- .../Content/routes/Settings/Invite.tsx | 0 .../Content/routes/Settings/NewTeam.tsx | 0 .../Content/routes/Settings/TeamSettings.tsx | 0 .../Content/routes/Settings/UserSettings.tsx | 0 .../routes/Settings/components/MemberList.tsx | 0 .../routes/Settings/components/index.tsx | 0 .../Content/routes/Settings/index.tsx | 0 .../routes/TeamView/AddTeamMember/index.tsx | 101 --- .../routes/TeamView/AddTeamMember/types.ts | 11 - .../routes/TeamView/InviteLink/index.tsx | 33 - .../routes/TeamView/InviteLink/types.ts | 3 - .../routes/TeamView/RemoveTeamMember/index.js | 91 -- .../Content/routes/TeamView/elements.js | 61 -- .../Content/routes/TeamView/index.js | 340 -------- .../Templates/BookmarkedTemplates/elements.ts | 9 - .../Templates/BookmarkedTemplates/index.tsx | 161 ---- .../BookmarkedTemplates/mutations.ts | 23 - .../Templates/Navigation/Navigation.tsx | 28 - .../routes/Templates/Navigation/elements.ts | 31 - .../routes/Templates/Navigation/index.ts | 1 - .../OwnedTemplates/OwnedTemplates.tsx | 139 ---- .../routes/Templates/OwnedTemplates/index.ts | 1 - .../Content/routes/Templates/Templates.tsx | 23 - .../Content/routes/Templates/elements.ts | 29 - .../Content/routes/Templates/index.ts | 1 - .../Content/routes/Templates/index.tsx | 0 .../Content/utils.ts | 0 .../Header/index.tsx | 0 .../Navigation/Actions/ExploreAction.tsx | 16 - .../Navigation/Actions/NewSandboxAction.tsx | 26 - .../Navigation/Actions/PatronAction.tsx | 19 - .../Navigation/Actions/SearchAction.tsx | 35 - .../Actions/ShowNotificationsAction.tsx | 40 - .../Dashboard/Navigation/Actions/index.ts | 5 - .../Navigation/Notifications/elements.ts | 91 -- .../Navigation/Notifications/index.tsx | 116 --- .../notifications/SandboxInvitation.tsx | 51 -- .../notifications/TeamAccepted.tsx | 27 - .../notifications/TeamInvite.tsx | 79 -- .../Notifications/notifications/elements.ts | 50 -- .../pages/Dashboard/Navigation/elements.ts | 95 --- .../app/pages/Dashboard/Navigation/index.tsx | 85 -- .../Sidebar/ContextMenu.tsx | 0 .../pages/Dashboard/Sidebar/Item/elements.js | 52 -- .../app/pages/Dashboard/Sidebar/Item/index.js | 116 --- .../FolderEntry/CreateFolderEntry.tsx | 116 --- .../SandboxesItem/FolderEntry/elements.ts | 47 -- .../SandboxesItem/FolderEntry/index.tsx | 434 ---------- .../Sidebar/SandboxesItem/elements.js | 8 - .../SandboxesItem/folder-drop-target.js | 162 ---- .../Dashboard/Sidebar/SandboxesItem/index.js | 149 ---- .../Dashboard/Sidebar/TemplateItem/index.tsx | 80 -- .../Dashboard/Sidebar/TrashItem/index.tsx | 73 -- .../Sidebar/WorkspaceSwitcher.tsx | 0 .../Sidebar/constants.ts | 0 .../app/pages/Dashboard/Sidebar/elements.ts | 30 - .../src/app/pages/Dashboard/Sidebar/index.tsx | 773 ++++++++++++++--- .../app/src/app/pages/Dashboard/elements.ts | 67 -- .../app/src/app/pages/Dashboard/index.tsx | 161 ++-- .../app/src/app/pages/Dashboard/queries.ts | 787 ++++++------------ .../{NewDashboard => Dashboard}/types.ts | 0 .../{NewDashboard => Dashboard}/utils/dnd.ts | 0 .../Dashboard/utils/get-child-collections.js | 12 +- .../app/pages/NewDashboard/Sidebar/index.tsx | 673 --------------- .../app/src/app/pages/NewDashboard/index.tsx | 128 --- .../app/src/app/pages/NewDashboard/queries.ts | 276 ------ .../get-direct-children.test.js.snap | 21 - .../utils/get-child-collections.js | 17 - .../NewDashboard/utils/get-direct-children.js | 37 - .../utils/get-direct-children.test.js | 33 - .../utils/get-most-used-template.js | 26 - packages/app/src/app/pages/index.tsx | 5 +- .../__snapshots__/index.test.tsx.snap | 3 - .../AutosizeInput/index.stories.tsx | 9 - .../components/AutosizeInput/index.test.tsx | 10 - .../src/components/AutosizeInput/index.tsx | 9 - .../__snapshots__/index.test.tsx.snap | 3 - .../AutosizeTextArea/index.stories.tsx | 8 - .../AutosizeTextArea/index.test.tsx | 10 - .../src/components/AutosizeTextArea/index.tsx | 4 - .../__snapshots__/index.test.tsx.snap | 5 - .../src/components/Checkbox/index.stories.tsx | 30 - .../src/components/Checkbox/index.test.tsx | 15 - .../common/src/components/Checkbox/index.tsx | 46 - .../__snapshots__/index.test.tsx.snap | 9 - .../src/components/CustomTemplate/elements.ts | 76 -- .../CustomTemplate/index.stories.tsx | 28 - .../components/CustomTemplate/index.test.tsx | 32 - .../src/components/CustomTemplate/index.tsx | 70 -- .../src/components/GridList/GridList.tsx | 62 -- .../common/src/components/GridList/Next.tsx | 11 - .../src/components/GridList/elements.ts | 59 -- .../common/src/components/GridList/index.ts | 1 - 182 files changed, 1051 insertions(+), 8972 deletions(-) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Breadcrumbs/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/EmptyScreen/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Filters/FilterOptions/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Filters/SortOptions/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Filters/ViewOptions/icons.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Filters/ViewOptions/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Folder/CreateFolder.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Folder/DragPreview.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Folder/FolderCard.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Folder/FolderListItem.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Folder/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Folder/types.ts (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Header/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Loading/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Repo/Icons.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Repo/ImportRepo.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Repo/RepoCard.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Repo/RepoListItem.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Repo/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Sandbox/NewMasterSandbox.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Sandbox/NewSandbox.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Sandbox/SandboxCard.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Sandbox/SandboxListItem.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Sandbox/TemplateIcon.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Sandbox/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Sandbox/types.ts (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Selection/ContextMenu.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Selection/ContextMenus/ContainerMenu.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Selection/ContextMenus/FolderMenu.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Selection/ContextMenus/MasterMenu.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Selection/ContextMenus/MultiItemMenu.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Selection/ContextMenus/RepoMenu.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Selection/ContextMenus/SandboxMenu.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Selection/ContextMenus/index.ts (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Selection/DragPreview.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/Selection/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Components/VariableGrid/index.tsx (100%) delete mode 100644 packages/app/src/app/pages/Dashboard/Content/DragLayer/SelectedSandboxItems/AnimatedSandboxItem.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/DragLayer/SelectedSandboxItems/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/DragLayer/SelectedSandboxItems/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/DragLayer/index.js delete mode 100644 packages/app/src/app/pages/Dashboard/Content/SandboxCard/KebabIcon.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/SandboxCard/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/SandboxCard/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/SandboxGrid/Row.js delete mode 100644 packages/app/src/app/pages/Dashboard/Content/SandboxGrid/elements.js delete mode 100644 packages/app/src/app/pages/Dashboard/Content/SandboxGrid/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Actions/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Actions/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/FilterOptions/Option.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/FilterOptions/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/FilterOptions/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/FieldToName.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/Option/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/Option/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Sandboxes/utils.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/Selection/index.js delete mode 100644 packages/app/src/app/pages/Dashboard/Content/elements.js delete mode 100644 packages/app/src/app/pages/Dashboard/Content/index.js rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/All/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/All/useFilteredItems.ts (100%) delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/CreateTeam/Plan/elements.js delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/CreateTeam/Plan/index.js delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/CreateTeam/elements.js delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/CreateTeam/index.js rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Deleted/index.tsx (100%) delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/DeletedSandboxes/index.js rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Drafts/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Home/index.tsx (100%) delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Folders.js delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Navigation/NavigationLink.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Navigation/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Navigation/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/elements.js delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/index.js rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Recent/index.tsx (100%) delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/RecentSandboxes/index.tsx rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Repositories/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Repositories/useFilteredItems.ts (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Search/index.tsx (100%) delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/SearchSandboxes/index.js rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Settings/Invite.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Settings/NewTeam.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Settings/TeamSettings.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Settings/UserSettings.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Settings/components/MemberList.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Settings/components/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Settings/index.tsx (100%) delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/TeamView/AddTeamMember/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/TeamView/AddTeamMember/types.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/TeamView/InviteLink/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/TeamView/InviteLink/types.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/TeamView/RemoveTeamMember/index.js delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/TeamView/elements.js delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/TeamView/index.js delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/Templates/BookmarkedTemplates/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/Templates/BookmarkedTemplates/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/Templates/BookmarkedTemplates/mutations.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/Templates/Navigation/Navigation.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/Templates/Navigation/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/Templates/Navigation/index.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/Templates/OwnedTemplates/OwnedTemplates.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/Templates/OwnedTemplates/index.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/Templates/Templates.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/Templates/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Content/routes/Templates/index.ts rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/routes/Templates/index.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Content/utils.ts (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Header/index.tsx (100%) delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/Actions/ExploreAction.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/Actions/NewSandboxAction.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/Actions/PatronAction.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/Actions/SearchAction.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/Actions/ShowNotificationsAction.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/Actions/index.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/Notifications/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/Notifications/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/SandboxInvitation.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/TeamAccepted.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/TeamInvite.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Navigation/index.tsx rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Sidebar/ContextMenu.tsx (100%) delete mode 100644 packages/app/src/app/pages/Dashboard/Sidebar/Item/elements.js delete mode 100644 packages/app/src/app/pages/Dashboard/Sidebar/Item/index.js delete mode 100644 packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/FolderEntry/CreateFolderEntry.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/FolderEntry/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/FolderEntry/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/elements.js delete mode 100644 packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/folder-drop-target.js delete mode 100644 packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/index.js delete mode 100644 packages/app/src/app/pages/Dashboard/Sidebar/TemplateItem/index.tsx delete mode 100644 packages/app/src/app/pages/Dashboard/Sidebar/TrashItem/index.tsx rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Sidebar/WorkspaceSwitcher.tsx (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/Sidebar/constants.ts (100%) delete mode 100644 packages/app/src/app/pages/Dashboard/Sidebar/elements.ts delete mode 100644 packages/app/src/app/pages/Dashboard/elements.ts rename packages/app/src/app/pages/{NewDashboard => Dashboard}/types.ts (100%) rename packages/app/src/app/pages/{NewDashboard => Dashboard}/utils/dnd.ts (100%) delete mode 100644 packages/app/src/app/pages/NewDashboard/Sidebar/index.tsx delete mode 100644 packages/app/src/app/pages/NewDashboard/index.tsx delete mode 100644 packages/app/src/app/pages/NewDashboard/queries.ts delete mode 100644 packages/app/src/app/pages/NewDashboard/utils/__snapshots__/get-direct-children.test.js.snap delete mode 100644 packages/app/src/app/pages/NewDashboard/utils/get-child-collections.js delete mode 100644 packages/app/src/app/pages/NewDashboard/utils/get-direct-children.js delete mode 100644 packages/app/src/app/pages/NewDashboard/utils/get-direct-children.test.js delete mode 100644 packages/app/src/app/pages/NewDashboard/utils/get-most-used-template.js delete mode 100644 packages/common/src/components/AutosizeInput/__snapshots__/index.test.tsx.snap delete mode 100644 packages/common/src/components/AutosizeInput/index.stories.tsx delete mode 100644 packages/common/src/components/AutosizeInput/index.test.tsx delete mode 100644 packages/common/src/components/AutosizeInput/index.tsx delete mode 100644 packages/common/src/components/AutosizeTextArea/__snapshots__/index.test.tsx.snap delete mode 100644 packages/common/src/components/AutosizeTextArea/index.stories.tsx delete mode 100644 packages/common/src/components/AutosizeTextArea/index.test.tsx delete mode 100644 packages/common/src/components/AutosizeTextArea/index.tsx delete mode 100644 packages/common/src/components/Checkbox/__snapshots__/index.test.tsx.snap delete mode 100644 packages/common/src/components/Checkbox/index.stories.tsx delete mode 100644 packages/common/src/components/Checkbox/index.test.tsx delete mode 100644 packages/common/src/components/Checkbox/index.tsx delete mode 100644 packages/common/src/components/CustomTemplate/__snapshots__/index.test.tsx.snap delete mode 100644 packages/common/src/components/CustomTemplate/elements.ts delete mode 100644 packages/common/src/components/CustomTemplate/index.stories.tsx delete mode 100644 packages/common/src/components/CustomTemplate/index.test.tsx delete mode 100644 packages/common/src/components/CustomTemplate/index.tsx delete mode 100644 packages/common/src/components/GridList/GridList.tsx delete mode 100644 packages/common/src/components/GridList/Next.tsx delete mode 100644 packages/common/src/components/GridList/elements.ts delete mode 100644 packages/common/src/components/GridList/index.ts diff --git a/packages/app/src/app/pages/NewDashboard/Components/Breadcrumbs/index.tsx b/packages/app/src/app/pages/Dashboard/Components/Breadcrumbs/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Breadcrumbs/index.tsx rename to packages/app/src/app/pages/Dashboard/Components/Breadcrumbs/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/EmptyScreen/index.tsx b/packages/app/src/app/pages/Dashboard/Components/EmptyScreen/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/EmptyScreen/index.tsx rename to packages/app/src/app/pages/Dashboard/Components/EmptyScreen/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Filters/FilterOptions/index.tsx b/packages/app/src/app/pages/Dashboard/Components/Filters/FilterOptions/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Filters/FilterOptions/index.tsx rename to packages/app/src/app/pages/Dashboard/Components/Filters/FilterOptions/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Filters/SortOptions/index.tsx b/packages/app/src/app/pages/Dashboard/Components/Filters/SortOptions/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Filters/SortOptions/index.tsx rename to packages/app/src/app/pages/Dashboard/Components/Filters/SortOptions/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Filters/ViewOptions/icons.tsx b/packages/app/src/app/pages/Dashboard/Components/Filters/ViewOptions/icons.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Filters/ViewOptions/icons.tsx rename to packages/app/src/app/pages/Dashboard/Components/Filters/ViewOptions/icons.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Filters/ViewOptions/index.tsx b/packages/app/src/app/pages/Dashboard/Components/Filters/ViewOptions/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Filters/ViewOptions/index.tsx rename to packages/app/src/app/pages/Dashboard/Components/Filters/ViewOptions/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Folder/CreateFolder.tsx b/packages/app/src/app/pages/Dashboard/Components/Folder/CreateFolder.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Folder/CreateFolder.tsx rename to packages/app/src/app/pages/Dashboard/Components/Folder/CreateFolder.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Folder/DragPreview.tsx b/packages/app/src/app/pages/Dashboard/Components/Folder/DragPreview.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Folder/DragPreview.tsx rename to packages/app/src/app/pages/Dashboard/Components/Folder/DragPreview.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Folder/FolderCard.tsx b/packages/app/src/app/pages/Dashboard/Components/Folder/FolderCard.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Folder/FolderCard.tsx rename to packages/app/src/app/pages/Dashboard/Components/Folder/FolderCard.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Folder/FolderListItem.tsx b/packages/app/src/app/pages/Dashboard/Components/Folder/FolderListItem.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Folder/FolderListItem.tsx rename to packages/app/src/app/pages/Dashboard/Components/Folder/FolderListItem.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Folder/index.tsx b/packages/app/src/app/pages/Dashboard/Components/Folder/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Folder/index.tsx rename to packages/app/src/app/pages/Dashboard/Components/Folder/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Folder/types.ts b/packages/app/src/app/pages/Dashboard/Components/Folder/types.ts similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Folder/types.ts rename to packages/app/src/app/pages/Dashboard/Components/Folder/types.ts diff --git a/packages/app/src/app/pages/NewDashboard/Components/Header/index.tsx b/packages/app/src/app/pages/Dashboard/Components/Header/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Header/index.tsx rename to packages/app/src/app/pages/Dashboard/Components/Header/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Loading/index.tsx b/packages/app/src/app/pages/Dashboard/Components/Loading/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Loading/index.tsx rename to packages/app/src/app/pages/Dashboard/Components/Loading/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Repo/Icons.tsx b/packages/app/src/app/pages/Dashboard/Components/Repo/Icons.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Repo/Icons.tsx rename to packages/app/src/app/pages/Dashboard/Components/Repo/Icons.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Repo/ImportRepo.tsx b/packages/app/src/app/pages/Dashboard/Components/Repo/ImportRepo.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Repo/ImportRepo.tsx rename to packages/app/src/app/pages/Dashboard/Components/Repo/ImportRepo.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Repo/RepoCard.tsx b/packages/app/src/app/pages/Dashboard/Components/Repo/RepoCard.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Repo/RepoCard.tsx rename to packages/app/src/app/pages/Dashboard/Components/Repo/RepoCard.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Repo/RepoListItem.tsx b/packages/app/src/app/pages/Dashboard/Components/Repo/RepoListItem.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Repo/RepoListItem.tsx rename to packages/app/src/app/pages/Dashboard/Components/Repo/RepoListItem.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Repo/index.tsx b/packages/app/src/app/pages/Dashboard/Components/Repo/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Repo/index.tsx rename to packages/app/src/app/pages/Dashboard/Components/Repo/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Sandbox/NewMasterSandbox.tsx b/packages/app/src/app/pages/Dashboard/Components/Sandbox/NewMasterSandbox.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Sandbox/NewMasterSandbox.tsx rename to packages/app/src/app/pages/Dashboard/Components/Sandbox/NewMasterSandbox.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Sandbox/NewSandbox.tsx b/packages/app/src/app/pages/Dashboard/Components/Sandbox/NewSandbox.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Sandbox/NewSandbox.tsx rename to packages/app/src/app/pages/Dashboard/Components/Sandbox/NewSandbox.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Sandbox/SandboxCard.tsx b/packages/app/src/app/pages/Dashboard/Components/Sandbox/SandboxCard.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Sandbox/SandboxCard.tsx rename to packages/app/src/app/pages/Dashboard/Components/Sandbox/SandboxCard.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Sandbox/SandboxListItem.tsx b/packages/app/src/app/pages/Dashboard/Components/Sandbox/SandboxListItem.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Sandbox/SandboxListItem.tsx rename to packages/app/src/app/pages/Dashboard/Components/Sandbox/SandboxListItem.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Sandbox/TemplateIcon.tsx b/packages/app/src/app/pages/Dashboard/Components/Sandbox/TemplateIcon.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Sandbox/TemplateIcon.tsx rename to packages/app/src/app/pages/Dashboard/Components/Sandbox/TemplateIcon.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Sandbox/index.tsx b/packages/app/src/app/pages/Dashboard/Components/Sandbox/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Sandbox/index.tsx rename to packages/app/src/app/pages/Dashboard/Components/Sandbox/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Sandbox/types.ts b/packages/app/src/app/pages/Dashboard/Components/Sandbox/types.ts similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Sandbox/types.ts rename to packages/app/src/app/pages/Dashboard/Components/Sandbox/types.ts diff --git a/packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenu.tsx b/packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenu.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenu.tsx rename to packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenu.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/ContainerMenu.tsx b/packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/ContainerMenu.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/ContainerMenu.tsx rename to packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/ContainerMenu.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/FolderMenu.tsx b/packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/FolderMenu.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/FolderMenu.tsx rename to packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/FolderMenu.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/MasterMenu.tsx b/packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/MasterMenu.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/MasterMenu.tsx rename to packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/MasterMenu.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/MultiItemMenu.tsx b/packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/MultiItemMenu.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/MultiItemMenu.tsx rename to packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/MultiItemMenu.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/RepoMenu.tsx b/packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/RepoMenu.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/RepoMenu.tsx rename to packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/RepoMenu.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/SandboxMenu.tsx b/packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/SandboxMenu.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/SandboxMenu.tsx rename to packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/SandboxMenu.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/index.ts b/packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/index.ts similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Selection/ContextMenus/index.ts rename to packages/app/src/app/pages/Dashboard/Components/Selection/ContextMenus/index.ts diff --git a/packages/app/src/app/pages/NewDashboard/Components/Selection/DragPreview.tsx b/packages/app/src/app/pages/Dashboard/Components/Selection/DragPreview.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Selection/DragPreview.tsx rename to packages/app/src/app/pages/Dashboard/Components/Selection/DragPreview.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/Selection/index.tsx b/packages/app/src/app/pages/Dashboard/Components/Selection/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/Selection/index.tsx rename to packages/app/src/app/pages/Dashboard/Components/Selection/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Components/VariableGrid/index.tsx b/packages/app/src/app/pages/Dashboard/Components/VariableGrid/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Components/VariableGrid/index.tsx rename to packages/app/src/app/pages/Dashboard/Components/VariableGrid/index.tsx diff --git a/packages/app/src/app/pages/Dashboard/Content/DragLayer/SelectedSandboxItems/AnimatedSandboxItem.tsx b/packages/app/src/app/pages/Dashboard/Content/DragLayer/SelectedSandboxItems/AnimatedSandboxItem.tsx deleted file mode 100644 index e0d543e1b9c..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/DragLayer/SelectedSandboxItems/AnimatedSandboxItem.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { Spring, animated, interpolate } from 'react-spring/renderprops'; - -import { - Container, - SandboxImageContainer, - SandboxImage, - SandboxInfo, -} from './elements'; - -type Props = { - id: string; - i: number; - x: number; - y: number; - scale: number; - isLast: boolean; - selectedSandboxes: Array; -}; - -export const AnimatedSandboxItem: React.FC = ({ - id, - i, - x, - y, - scale, - isLast, - selectedSandboxes, -}) => { - const [render, setRender] = useState(true); - const [position, setPosition] = useState(null); - - useEffect(() => { - let timeout: NodeJS.Timeout; - - const sandboxBrotherItem = document.getElementById(id); - - if (sandboxBrotherItem) { - setPosition(sandboxBrotherItem.getBoundingClientRect() as DOMRect); - } - - if (i !== 0 && !isLast) { - timeout = global.setTimeout(() => { - setRender(false); - }, 200); - } - - return () => { - if (timeout) { - global.clearTimeout(timeout); - } - }; - }, [id, i, isLast]); - - if (!render || !position) { - return null; - } - - return ( - el !== 'scale' : false} - from={{ x: position.x, y: position.y, shadow: 2, scale: 1 }} - to={{ scale, x, y, shadow: isLast ? 16 : 2 }} - key={id} - > - {({ x: newX, y: newY, scale: newScale, shadow: newShadow }) => ( - `0 ${s}px ${s * 2}px rgba(0, 0, 0, 0.3)` - ) - : 'inherit', - transform: interpolate( - [newX, newY, newScale], - (xx, yy, zz) => - `translate3d(${xx}px, ${yy}px, 0px) scale3d(${zz}, ${zz}, ${zz})` - ), - zIndex: i === 0 ? 20 : 10, - }} - > - - - - - - {selectedSandboxes.length}{' '} - {selectedSandboxes.length === 1 ? 'Sandbox' : 'Sandboxes'} - - - - )} - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/DragLayer/SelectedSandboxItems/elements.ts b/packages/app/src/app/pages/Dashboard/Content/DragLayer/SelectedSandboxItems/elements.ts deleted file mode 100644 index bc8b03d295e..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/DragLayer/SelectedSandboxItems/elements.ts +++ /dev/null @@ -1,30 +0,0 @@ -import styled from 'styled-components'; - -export const Container = styled.div` - height: 210px; - width: 346px; - - background-color: ${props => props.theme.background}; - border-radius: 2px; -`; - -export const SandboxImageContainer = styled.div` - display: flex; - justify-content: center; - align-items: stretch; - height: 160px; - - background-color: rgba(255, 255, 255, 0.1); -`; - -export const SandboxImage = styled.div` - background-size: contain; - background-position: 50%; - background-repeat: no-repeat; - width: 100%; -`; - -export const SandboxInfo = styled.div` - padding: 0.6rem 0.75rem; - font-size: 1em; -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/DragLayer/SelectedSandboxItems/index.tsx b/packages/app/src/app/pages/Dashboard/Content/DragLayer/SelectedSandboxItems/index.tsx deleted file mode 100644 index 26553d3bcfe..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/DragLayer/SelectedSandboxItems/index.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React, { useMemo } from 'react'; -import { useOvermind } from 'app/overmind'; - -import { AnimatedSandboxItem } from './AnimatedSandboxItem'; - -interface ISelectedSandboxItemsProps { - x: number; - y: number; - isOverPossibleTargets: boolean; - id: string; -} - -export const SelectedSandboxItems: React.FC = ({ - x, - y, - isOverPossibleTargets, - id, -}) => { - const { - state: { - dashboard: { selectedSandboxes }, - }, - } = useOvermind(); - - const selectedIds = useMemo( - () => [id, ...selectedSandboxes.filter(b => b !== id)], - [id, selectedSandboxes] - ); - - const scale = isOverPossibleTargets ? 0.4 : 0.8; - - return ( - <> - {selectedIds.map((sid, i) => ( - - ))} - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/DragLayer/index.js b/packages/app/src/app/pages/Dashboard/Content/DragLayer/index.js deleted file mode 100644 index d2c2d985e11..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/DragLayer/index.js +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react'; - -import { DragLayer as DNDDragLayer } from 'react-dnd'; - -import { SelectedSandboxItems } from './SelectedSandboxItems'; - -const layerStyles = { - position: 'fixed', - pointerEvents: 'none', - zIndex: 100, - left: 0, - top: 0, - width: '100%', - height: '100%', -}; - -function getItemCoords(props) { - const { currentOffset } = props; - - const { x, y } = currentOffset; - - return { - x, - y, - }; -} - -class CustomDragLayer extends React.Component { - renderItem(type, item, isOverPossibleTargets, { x, y }) { - if (type !== 'SANDBOX') { - return null; - } - return ( - - ); - } - - render() { - const { - item, - itemType, - isOverPossibleTargets, - currentOffset, - isDragging, - } = this.props; - - if (!isDragging || !currentOffset) { - return null; - } - - return ( -
-
- {this.renderItem( - itemType, - item, - isOverPossibleTargets, - getItemCoords(this.props) - )} -
-
- ); - } -} - -function collect(monitor) { - const isOverPossibleTargets = monitor.getTargetIds().length > 0; - return { - item: monitor.getItem(), - itemType: monitor.getItemType(), - currentOffset: monitor.getSourceClientOffset(), - isDragging: monitor.isDragging(), - isOverPossibleTargets, - }; -} - -export const DragLayer = DNDDragLayer(collect)(CustomDragLayer); diff --git a/packages/app/src/app/pages/Dashboard/Content/SandboxCard/KebabIcon.tsx b/packages/app/src/app/pages/Dashboard/Content/SandboxCard/KebabIcon.tsx deleted file mode 100644 index c910e4f2a16..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/SandboxCard/KebabIcon.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react'; -import IconBase from 'react-icons/lib/IconBase'; - -export const KebabIcon = ({ ...props }) => ( - - - - - - - -); diff --git a/packages/app/src/app/pages/Dashboard/Content/SandboxCard/elements.ts b/packages/app/src/app/pages/Dashboard/Content/SandboxCard/elements.ts deleted file mode 100644 index 841807eac5e..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/SandboxCard/elements.ts +++ /dev/null @@ -1,95 +0,0 @@ -import styled from 'styled-components'; -import fadeIn from '@codesandbox/common/lib/utils/animation/fade-in'; -import Tooltip from '@codesandbox/common/lib/components/Tooltip'; -import { ContextMenu } from 'app/components/ContextMenu'; -import { KebabIcon as MoreInfoIcon } from './KebabIcon'; - -export const PADDING = 32; - -export const Container = styled.div` - ${fadeIn(0)}; - background-color: ${props => props.theme.background}; - overflow: hidden; - border-radius: 2px; - user-select: none; - - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); -`; - -export const StyledContextMenu = styled(ContextMenu)<{ - isDraggingItem: boolean; -}>` - padding-right: ${PADDING}px; - box-sizing: border-box; - opacity: ${({ isDraggingItem }) => (isDraggingItem ? 0 : 1)}; -`; - -export const SandboxImageContainer = styled.div` - position: relative; - display: flex; - justify-content: center; - align-items: stretch; - height: 160px; - - background-color: rgba(255, 255, 255, 0.1); -`; - -export const SandboxImage = styled.div` - background-size: cover; - background-position: 50%; - background-repeat: no-repeat; - width: 100%; - z-index: 1; -`; - -export const SandboxInfo = styled.div` - position: relative; - display: flex; - padding: 0.6rem 0.75rem; - font-size: 0.875em; - - align-items: center; -`; - -export const SandboxTitle = styled.div` - display: flex; - align-items: center; -`; - -export const PrivacyIconContainer = styled(Tooltip)` - display: flex; - margin-left: 0.5rem; - color: rgba(255, 255, 255, 0.4); -`; - -export const SandboxDetails = styled.div` - font-size: 0.875em; - color: rgba(255, 255, 255, 0.5); - margin-top: 4px; -`; - -export const ImageMessage = styled.div` - position: absolute; - top: 0; - bottom: 0; - display: flex; - align-items: center; - font-weight: 600; - z-index: 0; - - font-size: 1.125rem; - color: rgba(255, 255, 255, 0.6); -`; - -export const KebabIcon = styled(MoreInfoIcon)` - transition: 0.3s ease color; - font-size: 1.75rem; - height: 16px; - width: 20px; - color: rgba(255, 255, 255, 0.6); - cursor: pointer; - - &:hover { - color: rgba(255, 255, 255, 0.8); - } -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/SandboxCard/index.tsx b/packages/app/src/app/pages/Dashboard/Content/SandboxCard/index.tsx deleted file mode 100644 index 5d155323ae3..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/SandboxCard/index.tsx +++ /dev/null @@ -1,697 +0,0 @@ -// @ts-check -/* eslint-disable react/prefer-stateless-function */ -import React from 'react'; -import history from 'app/utils/history'; -import { sandboxUrl } from '@codesandbox/common/lib/utils/url-generator'; -import { DragSource } from 'react-dnd'; -import { getEmptyImage } from 'react-dnd-html5-backend'; -import { Mutation } from 'react-apollo'; -import TrashIcon from 'react-icons/lib/md/delete'; - -import Unlisted from 'react-icons/lib/md/insert-link'; -import Private from 'react-icons/lib/md/lock'; - -import Input from '@codesandbox/common/lib/components/Input'; -import getTemplate, { TemplateType } from '@codesandbox/common/lib/templates'; -import theme from '@codesandbox/common/lib/theme'; -import track from '@codesandbox/common/lib/utils/analytics'; - -import { ESC, ENTER } from '@codesandbox/common/lib/utils/keycodes'; -import { SandboxFragment } from 'app/graphql/types'; -import { RENAME_SANDBOX_MUTATION } from '../../queries'; - -import { - Container, - SandboxImageContainer, - StyledContextMenu, - SandboxImage, - SandboxInfo, - SandboxDetails, - ImageMessage, - PrivacyIconContainer, - SandboxTitle, - KebabIcon, -} from './elements'; - -type Props = { - id: string; - title: string; - details: string; - selected: boolean; - color?: string; - template: TemplateType; - customTemplate: { color: string } | null; - screenshotUrl: string | undefined; - screenshotOutdated: boolean; - setSandboxesSelected: ( - ids: string[], - options?: { additive?: boolean; range?: boolean } - ) => void; - selectedCount: number; - collectionPath: string; // eslint-disable-line react/no-unused-prop-types - collectionTeamId: string | undefined; - sandbox: SandboxFragment; - page: string | undefined; - privacy: number; - isPatron: boolean; - isScrolling: () => boolean; - removedAt?: string; - style?: React.CSSProperties; - alias: string | undefined; - - setSandboxesPrivacy: (privacy: 0 | 1 | 2) => void; - deleteSandboxes: () => void; - exportSandboxes: () => void; - permanentlyDeleteSandboxes: () => void; - undeleteSandboxes: () => void; - makeTemplates: (teamId?: string) => void; - forkSandbox: (id: string) => void; - - // React-DnD, lazy typings - connectDragSource: any; - isDraggingItem: any; - connectDragPreview: any; -}; - -type State = { - renamingSandbox: boolean; - screenshotUrl: string | undefined; -}; - -export const DELETE_SANDBOX_DROP_KEY = 'delete'; -export const MAKE_TEMPLATE_DROP_KEY = 'makeTemplate'; - -const copyToClipboard = (str: string) => { - const el = document.createElement('textarea'); - el.value = str; - el.setAttribute('readonly', ''); - el.style.position = 'absolute'; - el.style.left = '-9999px'; - document.body.appendChild(el); - el.select(); - document.execCommand('copy'); - document.body.removeChild(el); -}; - -class SandboxItemComponent extends React.PureComponent { - el: HTMLDivElement; - screenshotTimeout: number; - - state: State = { - renamingSandbox: false, - screenshotUrl: null, - }; - - requestScreenshot = async () => { - const url = `/api/v1/sandboxes/${this.props.id}/screenshot.png`; - try { - await fetch(url); - } finally { - this.setState({ - screenshotUrl: url, - }); - } - }; - - getPrivacyIcon = () => { - if (this.props.privacy === 1) { - return ( - - - - ); - } - if (this.props.privacy === 2) { - return ( - - - - ); - } - - return null; - }; - - checkScreenshot() { - if (this.props.screenshotOutdated) { - if (this.hasScreenshot()) { - // We only request the screenshot if the sandbox card is in view for > 1 second - this.screenshotTimeout = window.setTimeout(() => { - this.requestScreenshot(); - }, 1000); - } - } else { - this.setState({ screenshotUrl: this.props.screenshotUrl }); - } - } - - UNSAFE_componentWillReceiveProps(nextProps) { - if (nextProps.id !== this.props.id) { - window.requestAnimationFrame(() => { - this.checkScreenshot(); - }); - } - } - - componentDidMount() { - if (this.props.selected) { - if ( - this.el && - typeof this.el.focus === 'function' && - !this.props.isScrolling() - ) { - this.el.focus(); - } - } - - const { connectDragPreview } = this.props; - if (connectDragPreview) { - // Use empty image as a drag preview so browsers don't draw it - // and we can draw whatever we want on the custom drag layer instead. - connectDragPreview(getEmptyImage(), { - // IE fallback: specify that we'd rather screenshot the node - // when it already knows it's being dragged so we can hide it with CSS. - captureDraggingState: true, - }); - } - - this.checkScreenshot(); - } - - componentWillUnmount() { - if (this.screenshotTimeout) { - clearTimeout(this.screenshotTimeout); - } - } - - getContextItems = () => { - const { selectedCount } = this.props; - if (this.props.removedAt) { - return [ - { - title: - selectedCount > 1 - ? `Recover ${selectedCount} Sandboxes` - : 'Recover Sandbox', - action: () => { - this.props.undeleteSandboxes(); - return true; - }, - }, - { - title: - selectedCount > 1 - ? `Delete ${selectedCount} Sandboxes Permanently` - : 'Delete Permanently', - action: () => { - this.props.permanentlyDeleteSandboxes(); - return true; - }, - color: theme.red.darken(0.2)(), - }, - ]; - } - - if (selectedCount > 1) { - const items = []; - - if (this.props.isPatron) { - items.push([ - { - title: `Make ${selectedCount} Sandboxes Public`, - action: () => { - this.props.setSandboxesPrivacy(0); - return true; - }, - }, - { - title: `Make ${selectedCount} Sandboxes Unlisted`, - action: () => { - this.props.setSandboxesPrivacy(1); - return true; - }, - }, - { - title: `Make ${selectedCount} Sandboxes Private`, - action: () => { - this.props.setSandboxesPrivacy(2); - return true; - }, - }, - ]); - } - return [ - ...items, - [ - { - title: `Export ${selectedCount} Sandboxes`, - action: () => { - this.props.exportSandboxes(); - return true; - }, - }, - ], - [ - selectedCount < 50 && { - title: `Make ${selectedCount} Sandboxes a Template`, - action: () => { - track('Template - Created', { - source: 'Context Menu', - count: selectedCount, - }); - this.props.makeTemplates(); - return true; - }, - }, - { - title: `Move ${selectedCount} Sandboxes To Trash`, - action: () => { - this.props.deleteSandboxes(); - return true; - }, - color: theme.red.darken(0.2)(), - }, - ], - ].filter(Boolean); - } - - return [ - (this.props.page === 'recent' || this.props.page === 'search') && [ - { - title: 'Show In Folder', - action: () => { - if (this.props.collectionTeamId) { - history.push( - `/dashboard/teams/${this.props.collectionTeamId}/sandboxes${this.props.collectionPath}` - ); - } else { - history.push(`/dashboard/sandboxes${this.props.collectionPath}`); - } - }, - }, - ], - [ - { - title: 'Open Sandbox', - action: this.openSandbox, - }, - { - title: 'Open Sandbox in new tab', - action: () => { - this.openSandbox(true); - return true; - }, - }, - { - title: 'Copy Sandbox Link', - action: () => { - this.copySandboxURL(); - return true; - }, - }, - { - title: 'Fork Sandbox', - action: () => { - this.props.forkSandbox(this.props.id); - return true; - }, - }, - { - title: 'Export Sandbox', - action: () => { - this.props.exportSandboxes(); - return true; - }, - }, - ], - this.props.isPatron && - [ - this.props.privacy !== 0 && { - title: 'Make Sandbox Public', - action: () => { - this.props.setSandboxesPrivacy(0); - return true; - }, - }, - this.props.privacy !== 1 && { - title: 'Make Sandbox Unlisted', - action: () => { - this.props.setSandboxesPrivacy(1); - return true; - }, - }, - this.props.privacy !== 2 && { - title: 'Make Sandbox Private', - action: () => { - this.props.setSandboxesPrivacy(2); - return true; - }, - }, - ].filter(Boolean), - [ - { - title: `Rename Sandbox`, - action: () => { - this.setState({ renamingSandbox: true }); - return true; - }, - }, - { - title: `Make Sandbox a Template`, - action: () => { - track('Template - Created', { - source: 'Context Menu', - count: 1, - }); - this.props.makeTemplates(); - return true; - }, - }, - { - title: `Move to Trash`, - action: () => { - this.props.deleteSandboxes(); - return true; - }, - color: theme.red.darken(0.2)(), - }, - ], - ].filter(Boolean); - }; - - selectSandbox = (e: React.MouseEvent | React.FocusEvent) => { - this.props.setSandboxesSelected([this.props.id], { - additive: 'metaKey' in e ? e.metaKey : false, - range: 'shiftKey' in e ? e.shiftKey : false, - }); - }; - - openSandbox = (openNewWindow = false) => { - // @ts-ignore Git sandboxes aren't shown here anyway - const url = sandboxUrl({ id: this.props.id, alias: this.props.alias }); - - if (!this.props.removedAt) { - if (openNewWindow === true) { - track('Dashboard - Sandbox Opened in a new tab'); - window.open(url, '_blank'); - } else { - history.push(url); - } - } - - return true; - }; - - copySandboxURL = () => { - const url = sandboxUrl({ id: this.props.id, alias: this.props.alias }); - // TODO: Use effects.browse.copyToClipboard after refactoring to Function Component - copyToClipboard(`https://codesandbox.io${url}`); - - return true; - }; - - handleMouseDown = (e: React.MouseEvent) => { - e.stopPropagation(); - - if (!this.props.selected || e.metaKey) { - this.selectSandbox(e); - } - }; - - handleKeyDown = (e: React.KeyboardEvent) => { - if (e.keyCode === ENTER) { - track('Dashboard - Sandbox Opened With Enter'); - // enter - this.openSandbox(); - } - }; - - handleOnContextMenu = (e: React.MouseEvent) => { - track('Dashboard - Sandbox Context Menu Opened'); - if (!this.props.selected) { - this.selectSandbox(e); - } - }; - - handleOnFocus = (e: React.FocusEvent) => { - if (!this.props.selected) { - this.selectSandbox(e); - } - }; - - handleOnBlur = (e: React.FocusEvent) => { - if (this.props.selected && e.bubbles) { - this.props.setSandboxesSelected([]); - } - }; - - getImageMessage = () => { - if (this.props.removedAt) { - return ( - - ); - } - - if (this.props.privacy === 2) { - return ( - - ); - } - - const templateDefinition = getTemplate(this.props.template); - - if (templateDefinition.isServer) { - return `Container Sandbox`; - } - - if (process.env.STAGING) { - return `Staging Sandbox`; - } - - return `Generating Screenshot...`; - }; - - hasScreenshot = () => { - const templateDefinition = getTemplate(this.props.template); - - if (templateDefinition.isServer) { - return false; - } - - return !this.props.removedAt && this.props.privacy !== 2; - }; - - render() { - const { - style, - id, - title, - details, - color, - template, - connectDragSource, - isDraggingItem, - selected, - } = this.props; - - const templateInfo = getTemplate(template); - - return ( - - {onContextMenu => - connectDragSource( -
- { - onContextMenu(e); - this.handleOnContextMenu(e); - }} - onDoubleClick={event => { - // check for cmd click - const cmd = event.ctrlKey || event.metaKey; - - this.openSandbox(Boolean(cmd)); - }} - onBlur={this.handleOnBlur} - onFocus={this.handleOnFocus} - onKeyDown={this.handleKeyDown} - ref={el => { - this.el = el; - }} - role="button" - tabIndex={0} - > - - {this.getImageMessage()} - - {this.hasScreenshot() && ( - - )} - - -
-
-
- {this.state.renamingSandbox ? ( - - {mutate => { - let input = null; - - const saveName = () => { - this.setState({ renamingSandbox: false }); - - if (input.value !== title) { - mutate({ - variables: { - title: input.value, - id: this.props.id, - }, - optimisticResponse: { - __typename: 'Mutation', - renameSandbox: { - __typename: 'Sandbox', - ...this.props.sandbox, - title: input.value, - }, - }, - }); - } - }; - - return ( - { - input = node; - if (node) { - node.select(); - } - }} - onKeyDown={e => { - if (e.keyCode === ENTER) { - e.preventDefault(); - e.stopPropagation(); - - saveName(); - } else if (e.keyCode === ESC) { - e.preventDefault(); - e.stopPropagation(); - - this.setState({ renamingSandbox: false }); - } - }} - onBlur={saveName} - block - defaultValue={title} - /> - ); - }} - - ) : ( - - {title} {this.getPrivacyIcon()} - - )} -
- {details} -
- - - -
- ) - } - - ); - } -} - -/** - * Implements the drag source contract. - */ -const cardSource = { - beginDrag(props) { - track('Dashboard - Sandbox Dragged'); - props.setDragging({ isDragging: true }); - - return { - left: props.style.left, - top: props.style.top, - id: props.id, - collectionPath: props.collectionPath, - collectionTeamId: props.collectionTeamId, - removedAt: props.removedAt, - }; - }, - - endDrag(props, monitor) { - props.setDragging({ isDragging: false }); - - const result = monitor.getDropResult(); - - if (result && result[DELETE_SANDBOX_DROP_KEY]) { - props.deleteSandboxes(); - } - - if (result && result[MAKE_TEMPLATE_DROP_KEY]) { - track('Template - Created', { - source: 'Dragging', - team: !!result.teamId, - }); - props.makeTemplates(result.teamId); - } - }, -}; - -/** - * Specifies the props to inject into your component. - */ -function collect(connect) { - return { - connectDragSource: connect.dragSource(), - connectDragPreview: connect.dragPreview(), - }; -} - -export const SandboxItem = DragSource( - 'SANDBOX', - cardSource, - collect -)(SandboxItemComponent); diff --git a/packages/app/src/app/pages/Dashboard/Content/SandboxGrid/Row.js b/packages/app/src/app/pages/Dashboard/Content/SandboxGrid/Row.js deleted file mode 100644 index a3512c22ef3..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/SandboxGrid/Row.js +++ /dev/null @@ -1,64 +0,0 @@ -/** @flow */ -import * as React from 'react'; - -/** - * Default row renderer for Table. - */ -export default function defaultRowRenderer({ - className, - columns, - index, - key, - onRowClick, - onRowDoubleClick, - onRowMouseOut, - onRowMouseOver, - onRowRightClick, - selectSandboxes, - rowData, - style, - id, -}) { - const a11yProps = {}; - - a11yProps['aria-label'] = 'row'; - a11yProps.tabIndex = 0; - - if (onRowClick) { - a11yProps.onClick = event => onRowClick({ event, index, rowData }); - } - if (onRowDoubleClick) { - a11yProps.onDoubleClick = event => - onRowDoubleClick({ event, index, rowData }); - } - if (onRowMouseOut) { - a11yProps.onMouseOut = event => onRowMouseOut({ event, index, rowData }); - } - if (onRowMouseOver) { - a11yProps.onMouseOver = event => onRowMouseOver({ event, index, rowData }); - } - if (onRowRightClick) { - a11yProps.onContextMenu = event => - onRowRightClick({ event, index, rowData }); - } - - return ( -
{ - e.preventDefault(); - e.stopPropagation(); - - selectSandboxes([id], { additive: e.metaKey, range: e.shiftKey }); - }} - className={className} - key={key} - role="row" - style={style} - id={id} - tabIndex="0" - > - {columns} -
- ); -} diff --git a/packages/app/src/app/pages/Dashboard/Content/SandboxGrid/elements.js b/packages/app/src/app/pages/Dashboard/Content/SandboxGrid/elements.js deleted file mode 100644 index 6da4e189a99..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/SandboxGrid/elements.js +++ /dev/null @@ -1,29 +0,0 @@ -import styled, { css } from 'styled-components'; -import Row from './Row'; - -export const StyledRow = styled(Row)` - font-weight: 600; - user-select: none; - - ${props => - props.selected && - css` - background-color: ${props.theme.secondary.clearer(0.9)}; - color: ${props.theme.secondary}; - `}; - &:focus { - outline: none; - } -`; - -export const Content = styled.div` - width: 100%; - height: calc(100% - 23px); - padding-top: 2rem; - box-sizing: border-box; - - @media (max-width: 768px) { - width: calc(100% - 30px); - margin-left: 30px; - } -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/SandboxGrid/index.tsx b/packages/app/src/app/pages/Dashboard/Content/SandboxGrid/index.tsx deleted file mode 100644 index e176453deba..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/SandboxGrid/index.tsx +++ /dev/null @@ -1,543 +0,0 @@ -import 'react-virtualized/styles.css'; - -import { basename } from 'path'; - -import track from '@codesandbox/common/lib/utils/analytics'; -import { getSandboxName } from '@codesandbox/common/lib/utils/get-sandbox-name'; -import { protocolAndHost } from '@codesandbox/common/lib/utils/url-generator'; -import { makeTemplates } from 'app/components/CreateNewSandbox/queries'; -import downloadZip from 'app/overmind/effects/zip/create-zip'; -import { formatDistanceToNow } from 'date-fns'; -import { zonedTimeToUtc } from 'date-fns-tz'; -import { camelizeKeys } from 'humps'; -import { uniq } from 'lodash-es'; -import React from 'react'; -import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer'; -import Grid from 'react-virtualized/dist/commonjs/Grid'; -import Table from 'react-virtualized/dist/commonjs/Table'; -import Column from 'react-virtualized/dist/commonjs/Table/Column'; - -import { SandboxFragment } from 'app/graphql/types'; -import { Sandbox } from '@codesandbox/common/lib/types'; -import { - deleteSandboxes, - permanentlyDeleteSandboxes, - setSandboxesPrivacy, - undeleteSandboxes, -} from '../../queries'; -import { DragLayer } from '../DragLayer'; -import { SandboxItem } from '../SandboxCard'; -import { PADDING } from '../SandboxCard/elements'; -import { Selection, getBounds } from '../Selection'; -import { Content, StyledRow } from './elements'; - -type State = { - selection: - | { - startX: number; - startY: number; - endX: number; - endY: number; - } - | undefined; - localSandboxesSelected: string[] | null; -}; - -const BASE_WIDTH = 300; -const BASE_HEIGHT = 242; -const IS_TABLE = false; - -const diff = (a, b) => (a > b ? a - b : b - a); -const distanceInWordsToNow = date => - formatDistanceToNow(zonedTimeToUtc(date, 'Etc/UTC')); - -interface ISandboxGridComponentProps { - page?: 'search' | 'recent'; - ExtraElement: React.ComponentType<{ style?: React.CSSProperties }>; - sandboxes: SandboxFragment[]; - selectedSandboxes: string[]; - orderByField: string; - isDragging: boolean; - isPatron: boolean; - sandboxesSelected: (params: { sandboxIds: string[] }) => void; - forkExternalSandbox: (params: { sandboxId: string }) => void; - dragChanged: (params: { isDragging: boolean }) => void; -} - -class SandboxGridComponent extends React.Component< - ISandboxGridComponentProps, - State -> { - state = { - selection: undefined, - localSandboxesSelected: null, - }; - - selectedSandboxesObject: { [id: string]: true }; - loadedSandboxes: { [id: string]: Sandbox } = {}; - scrolling: boolean; - isDragging: boolean; - columnCount: number; - - getSelectedSandboxIds = () => { - const { selectedSandboxes: selectedSandboxesFromState } = this.props; - const { localSandboxesSelected } = this.state; - - return localSandboxesSelected === null - ? selectedSandboxesFromState - : localSandboxesSelected; - }; - - commitSandboxesSelected = () => { - this.props.sandboxesSelected({ - sandboxIds: this.state.localSandboxesSelected || [], - }); - this.setState({ - localSandboxesSelected: null, - }); - }; - - setSandboxesSelected = ( - ids, - { additive = false, range = false, delay = false } = {} - ) => { - const { sandboxes } = this.props; - - const selectedSandboxes = this.getSelectedSandboxIds(); - - const setSelected = (sandboxIds: string[]) => { - /** - * If delay is true we don't commit to the store yet, but we keep it in this component. - * This is for performance reasons when having a selection. On mouseup we commit the selection - * to the store. - */ - if (delay) { - this.setState({ - localSandboxesSelected: sandboxIds, - }); - } else { - this.props.sandboxesSelected({ - sandboxIds, - }); - this.setState({ - localSandboxesSelected: null, - }); - } - }; - - if (range === true) { - if (!delay) { - track('Dashboard - Sandbox Shift Selection'); - } - const indexedSandboxes = sandboxes.map((sandbox, i) => ({ sandbox, i })); - - // We need to select a range - const firstIndexInfo = indexedSandboxes.find(({ sandbox }) => - selectedSandboxes.includes(sandbox.id) - ); - - const [id] = ids; - - const lastIndexInfo = indexedSandboxes.find( - ({ sandbox }) => sandbox.id === id - ); - - if (firstIndexInfo && lastIndexInfo) { - const indexes = [firstIndexInfo.i, lastIndexInfo.i].sort(); - const sandboxIds = indexedSandboxes - .map(({ sandbox }) => sandbox.id) - .slice(indexes[0], indexes[1] + 1); - - setSelected(sandboxIds); - return; - } - } - - let sandboxIds = ids; - - if (additive) { - if (!delay) { - track('Dashboard - Sandbox Additive Selection'); - } - sandboxIds = selectedSandboxes.filter(id => !ids.includes(id)); - const additiveIds = ids.filter(id => !selectedSandboxes.includes(id)); - - sandboxIds = uniq([...sandboxIds, ...additiveIds]); - } - - setSelected(sandboxIds); - }; - - makeTemplates = (teamId?: string) => { - const collections = uniq( - this.props.sandboxes - .filter(sandbox => this.selectedSandboxesObject[sandbox.id]) - .map(s => s.collection) - ); - - makeTemplates(this.props.selectedSandboxes, teamId, collections); - }; - - deleteSandboxes = () => { - const collections = uniq( - this.props.sandboxes - .filter(sandbox => this.selectedSandboxesObject[sandbox.id]) - .map(s => s.collection) - ); - deleteSandboxes(this.props.selectedSandboxes, collections); - }; - - undeleteSandboxes = () => { - undeleteSandboxes(this.props.selectedSandboxes); - }; - - permanentlyDeleteSandboxes = () => { - permanentlyDeleteSandboxes(this.props.selectedSandboxes); - }; - - setSandboxesPrivacy = (privacy: 0 | 1 | 2) => { - track('Sandbox - Update Privacy', { - privacy, - source: 'dashboard', - }); - setSandboxesPrivacy(this.props.selectedSandboxes, privacy); - }; - - getSandbox = async sandboxId => { - if (this.loadedSandboxes[sandboxId]) { - return Promise.resolve(this.loadedSandboxes[sandboxId]); - } - - return fetch(`${protocolAndHost()}/api/v1/sandboxes/${sandboxId}`, { - headers: { - 'Content-Type': 'application/json', - }, - }) - .then(x => x.json()) - .then(x => { - const data = camelizeKeys(x.data) as Sandbox; - this.loadedSandboxes[data.id] = data; - return data; - }); - }; - - exportSandboxes = async () => { - const sandboxIds = uniq( - this.props.sandboxes - .filter(sandbox => this.selectedSandboxesObject[sandbox.id]) - .map(s => s.id) - ); - const sandboxes = await Promise.all( - sandboxIds.map(s => this.getSandbox(s)) - ); - return Promise.all( - sandboxes.map(s => downloadZip(s, s.modules, s.directories)) - ); - }; - - forkSandbox = id => { - this.props.forkExternalSandbox({ sandboxId: id }); - }; - - onMouseDown = (event: React.MouseEvent) => { - this.setState({ - selection: { - startX: event.clientX, - startY: event.clientY, - endX: event.clientX, - endY: event.clientY, - }, - }); - - if (!event.metaKey) { - this.setSandboxesSelected([]); - } - - document.addEventListener('mousemove', this.onMouseMove); - document.addEventListener('mouseup', this.onMouseUp); - }; - - onMouseUp = () => { - if ( - this.state.selection && - (diff(this.state.selection.startX, this.state.selection.endX) > 50 || - diff(this.state.selection.startY, this.state.selection.endY) > 50) - ) { - track('Dashboard - Sandbox Selection Done'); - } - - document.removeEventListener('mousemove', this.onMouseMove); - document.removeEventListener('mouseup', this.onMouseUp); - this.setState( - { - selection: undefined, - }, - () => { - this.commitSandboxesSelected(); - } - ); - }; - - onMouseMove = event => { - if (this.state.selection) { - const newSelection = { - ...this.state.selection, - endX: event.clientX, - endY: event.clientY, - }; - // eslint-disable-next-line - this.setState(state => ({ - selection: newSelection, - })); - - const sandboxes = document.querySelectorAll('.sandbox-item'); - const selectedSandboxes = []; - const selection = getBounds( - newSelection.startX, - newSelection.startY, - newSelection.endX, - newSelection.endY - ); - - /* eslint-disable no-restricted-syntax */ - // @ts-ignore - for (const sandbox of sandboxes) { - const { top, height, left, width } = sandbox.getBoundingClientRect(); - const padding = IS_TABLE ? 0 : PADDING; - const boxWidth = width - padding; - const boxHeight = height - padding; - - if ( - (left >= selection.left || left + boxWidth >= selection.left) && - left <= selection.left + selection.width && - (top >= selection.top || top + boxHeight >= selection.top) && - top <= selection.top + selection.height - ) { - selectedSandboxes.push(sandbox); - } - } - /* eslint-enable */ - - this.setSandboxesSelected( - selectedSandboxes.map(el => el.id), - { - additive: event.metaKey, - delay: true, - } - ); - } - }; - - isScrolling = () => this.scrolling; - - cellRenderer = ({ rowIndex, columnIndex, key, style, isScrolling }) => { - this.scrolling = isScrolling; - - let index = rowIndex * this.columnCount + columnIndex; - const { sandboxes, ExtraElement } = this.props; - - if (ExtraElement) { - if (index === 0) { - return ; - } - - index--; - } - - if (index > sandboxes.length - 1) { - return null; - } - - const item = sandboxes[index]; - - const getOrder = () => { - if (item.removedAt) { - return `Deleted ${distanceInWordsToNow(item.removedAt)} ago`; - } - - const orderField = this.props.orderByField; - if (orderField === 'insertedAt') { - return `Created ${distanceInWordsToNow(item.insertedAt)} ago`; - } - - return `Edited ${distanceInWordsToNow(item.updatedAt)} ago`; - }; - - let editedSince = getOrder(); - - if (this.props.page === 'search' || this.props.page === 'recent') { - const dir = item.collection?.path - ? basename(item.collection.path) - : item.teamId - ? 'Team Sandboxes' - : 'My Sandboxes'; - - if (dir) { - editedSince += ` in ${dir}`; - } - } - - const itemInSelection = this.selectedSandboxesObject[item.id]; - - return ( - - ); - }; - - rowRenderer = props => { - const selected = this.selectedSandboxesObject[props.rowData.id]; - return ( - - ); - }; - - render() { - const { selection } = this.state; - const { sandboxes, isDragging } = this.props; - - let sandboxCount = sandboxes.length; - - this.isDragging = isDragging; - this.selectedSandboxesObject = {}; - // Create an object to make it O(1) - this.getSelectedSandboxIds().forEach(id => { - this.selectedSandboxesObject[id] = true; - }); - - return ( - - - - {({ width, height }) => { - if (this.props.ExtraElement) { - sandboxCount += 1; - } - - const columnCount = Math.max( - 1, - Math.floor(width / (BASE_WIDTH + PADDING)) - ); - const rowCount = Math.ceil(sandboxCount / columnCount); - const columnWidth = width / columnCount; - this.columnCount = columnCount; - - if (IS_TABLE) { - return ( - sandboxes[index]} - headerStyle={{ - color: 'white', - }} - rowStyle={{ - fontSize: '.875rem', - }} - > - - rowData.title || rowData.id - } - width={200} - /> - - - distanceInWordsToNow(rowData.updatedAt) + ' ago' - } - width={150} - /> - - distanceInWordsToNow(rowData.insertedAt) + ' ago' - } - width={150} - /> - rowData.source.template} - width={150} - /> -
- ); - } - - return ( - - ); - }} -
- - {selection && } -
- ); - } -} - -export const SandboxGrid = SandboxGridComponent; diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Actions/elements.ts b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Actions/elements.ts deleted file mode 100644 index fa3dc883c64..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Actions/elements.ts +++ /dev/null @@ -1,36 +0,0 @@ -import styled from 'styled-components'; - -export const Container = styled.div` - display: flex; - align-items: center; - font-size: 0.875rem; - color: rgba(255, 255, 255, 0.8); - margin-right: 3rem; -`; - -export const VanillaButton = styled.button` - transition: 0.3s ease color; - background-color: transparent; - display: flex; - border: 0; - outline: 0; - padding: 0; - margin: 0; - color: rgba(255, 255, 255, 0.8); - vertical-align: middle; - align-items: center; - - cursor: pointer; - - &:focus { - color: white; - } - - &:hover { - color: white; - } - - svg { - margin-left: 0.5rem; - } -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Actions/index.tsx b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Actions/index.tsx deleted file mode 100644 index ddc9bf76aa6..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Actions/index.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; - -import { Container, VanillaButton } from './elements'; - -export interface IAction { - name: string; - run: () => void; - Icon: React.FunctionComponentElement; -} - -interface Props { - actions?: IAction[]; -} - -export function DashboardActions({ actions = [] }: Props) { - return ( - - {actions.map(action => ( - action.run()}> - {action.name} {action.Icon} - - ))} - - ); -} diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/FilterOptions/Option.tsx b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/FilterOptions/Option.tsx deleted file mode 100644 index f8129833f6a..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/FilterOptions/Option.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; - -import { Option as Container, OptionName, CheckBox } from './elements'; - -interface Props { - color: string; - id: string; - style?: React.CSSProperties; - niceName: string; - selected: boolean; - toggleTemplate: (name: string, selected: boolean) => void; -} - -export const Option = ({ - color, - id, - style, - niceName, - selected, - toggleTemplate, -}: Props) => { - const checkBoxName = `${id}-checkbox`; - return ( - { - e.preventDefault(); - toggleTemplate(id, !selected); - }} - onMouseDown={e => { - e.preventDefault(); - }} - style={style} - > - - - {niceName} - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/FilterOptions/elements.ts b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/FilterOptions/elements.ts deleted file mode 100644 index adfc226c56c..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/FilterOptions/elements.ts +++ /dev/null @@ -1,115 +0,0 @@ -import styled, { css } from 'styled-components'; - -export const Container = styled.div<{ hideFilters: boolean }>` - ${({ hideFilters }) => css` - transition: 0.3s ease opacity; - position: relative; - color: rgba(255, 255, 255, 0.6); - font-size: 0.875rem; - - margin-right: 1rem; - vertical-align: middle; - - ${hideFilters && - css` - opacity: 0.5; - pointer-events: none; - `}; - `}; -`; - -export const TemplatesName = styled.span` - transition: 0.3s ease color; - color: rgba(255, 255, 255, 0.8); - - cursor: pointer; - - &:hover { - color: white; - } -`; - -export const OverlayContainer = styled.div` - ${({ theme }) => css` - overflow: hidden; - box-sizing: border-box; - right: 0; - text-align: left; - line-height: 1.6; - width: 300px; - padding: 1rem; - z-index: 10; - color: rgba(255, 255, 255, 0.8); - font-size: 0.875rem; - - border-radius: 2px; - box-shadow: 0 3px 3px rgba(0, 0, 0, 0.3); - - background-color: ${theme.background}; - `}; -`; - -export const OptionName = styled.span` - font-weight: 600; - cursor: pointer; -`; - -export const Option = styled.div<{ selected: boolean }>` - ${({ selected, theme }) => css` - transition: 0.3s ease color; - cursor: pointer; - color: ${theme.light ? 'rgba(0, 0, 0, 0.7)' : 'rgba(255, 255, 255, 0.7)'}; - - margin-bottom: 0.25rem; - - &:hover { - color: rgba(255, 255, 255, 0.9); - - ${!selected && - css` - span { - border-color: rgba(255, 255, 255, 0.1); - } - `}; - } - - &:last-child { - margin-bottom: 0; - } - - ${selected && - css` - color: white; - `}; - `}; -`; - -export const CheckBox = styled.span<{ color: string; selected: boolean }>` - ${({ color, selected }) => css` - ${selected - ? css` - background: ${color} url('') no-repeat 50%/10px; - background-image: url("data:image/svg+xml;utf8,"); - ` - : css` - background: rgba(0, 0, 0, 0.3) url('') no-repeat 50%/10px; - background-image: url("data:image/svg+xml;utf8, = ({ - possibleTemplates = [], - hideFilters = false, -}) => { - const { - actions: { - dashboard: { - blacklistedTemplateAdded, - blacklistedTemplateRemoved, - blacklistedTemplatesChanged, - blacklistedTemplatesCleared, - }, - }, - state: { - dashboard: { - filters: { blacklistedTemplates }, - isTemplateSelected, - }, - }, - } = useOvermind(); - - const toggleTemplate = (name: string, select: boolean) => - select ? blacklistedTemplateRemoved(name) : blacklistedTemplateAdded(name); - const allSelected = possibleTemplates.every(({ id }) => - isTemplateSelected(id) - ); - - const Overlay = () => ( - - {possibleTemplates.length > 0 ? ( - <> - {orderBy(possibleTemplates, 'niceName').map( - ({ color, id, name, niceName }) => { - const selected = isTemplateSelected(id); - - return ( - - ); - } - )} - - - ); - - const templateCount = possibleTemplates.length - blacklistedTemplates.length; - const templateMessage = - templateCount === possibleTemplates.length && templateCount > 0 - ? 'all environments' - : `${Math.max(0, templateCount)} ${ - templateCount === 1 ? 'environment' : 'environments' - }`; - - return ( - - {open => ( - - Showing{' '} - {templateMessage} - - )} - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/FieldToName.ts b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/FieldToName.ts deleted file mode 100644 index 65ff64643a1..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/FieldToName.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const FIELD_TO_NAME = { - insertedAt: 'Last Created', - updatedAt: 'Last Modified', - title: 'Name', -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/Option/elements.ts b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/Option/elements.ts deleted file mode 100644 index b36a9417537..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/Option/elements.ts +++ /dev/null @@ -1,35 +0,0 @@ -import styled, { css } from 'styled-components'; - -export const Container = styled.a<{ - selected: boolean; -}>` - ${({ selected, theme }) => css` - transition: 0.3s ease color; - display: flex; - vertical-align: middle; - align-items: center; - margin-bottom: 0.5rem; - color: ${theme.light ? 'rgba(0, 0, 0, 0.7)' : 'rgba(255, 255, 255, 0.7)'}; - text-decoration: none; - cursor: pointer; - font-weight: 600; - - &:last-child { - margin-bottom: 0; - } - - &:hover { - color: white; - } - - ${selected && - css` - color: white; - `}; - `}; -`; - -export const IconContainer = styled.div` - width: 1rem; - margin-right: 0.5rem; -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/Option/index.tsx b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/Option/index.tsx deleted file mode 100644 index fd2632a1eca..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/Option/index.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React, { FunctionComponent } from 'react'; -import Check from 'react-icons/lib/md/check'; - -import { Container, IconContainer } from './elements'; - -type Props = { - currentField: string; - field: string; - name: string; - setField: (field: string) => void; -}; -export const Option: FunctionComponent = ({ - currentField, - field, - name, - setField, -}) => { - const selected = field === currentField; - - return ( - setField(field)} selected={selected}> - {selected && } {name} - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/elements.ts b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/elements.ts deleted file mode 100644 index ee437bf9c33..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/elements.ts +++ /dev/null @@ -1,21 +0,0 @@ -import styled, { css } from 'styled-components'; - -export const Container = styled.div` - ${({ theme }) => css` - overflow: hidden; - box-sizing: border-box; - right: 0; - text-align: left; - line-height: 1.6; - width: 200px; - padding: 1rem; - z-index: 10; - color: rgba(255, 255, 255, 0.8); - font-size: 0.875rem; - - border-radius: 2px; - box-shadow: 0 3px 3px rgba(0, 0, 0, 0.3); - - background-color: ${theme.background}; - `}; -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/index.tsx b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/index.tsx deleted file mode 100644 index 1decae7149f..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/Overlay/index.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React, { FunctionComponent } from 'react'; - -import { useOvermind } from 'app/overmind'; - -import { FIELD_TO_NAME } from '../FieldToName'; - -import { Container } from './elements'; -import { Option } from './Option'; - -export const Overlay: FunctionComponent = () => { - const { - actions: { - dashboard: { orderByChanged }, - }, - state: { - dashboard: { - orderBy: { field: currentField, order }, - }, - }, - } = useOvermind(); - - const setField = (field: string) => orderByChanged({ field, order }); - - return ( - - - - - - - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/elements.ts b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/elements.ts deleted file mode 100644 index 38709d79e65..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/elements.ts +++ /dev/null @@ -1,49 +0,0 @@ -import ArrowDown from 'react-icons/lib/md/arrow-downward'; -import styled, { css } from 'styled-components'; - -import { OrderBy } from 'app/overmind/namespaces/dashboard/types'; - -export const Container = styled.div<{ - hideOrder: boolean; -}>` - ${({ hideOrder }) => css` - transition: 0.3s ease opacity; - color: rgba(255, 255, 255, 0.6); - font-size: 0.875rem; - width: 175px; - text-align: right; - display: flex; - - ${hideOrder && - css` - opacity: 0.5; - pointer-events: none; - `}; - `}; -`; - -export const OrderName = styled.span` - transition: 0.3s ease color; - color: rgba(255, 255, 255, 0.8); - cursor: pointer; - margin-left: 1em; - - &:hover { - color: white; - } -`; - -export const Arrow = styled(ArrowDown)<{ order: OrderBy['order'] }>` - ${({ order }) => css` - transition: 0.3s ease all; - cursor: pointer; - font-size: 0.875rem; - margin-bottom: 2px; - margin-left: 4px; - transform: rotate(${order === 'asc' ? -180 : 0}deg); - - &:hover { - color: white; - } - `}; -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/index.tsx b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/index.tsx deleted file mode 100644 index 2781841c937..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/SortOptions/index.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import React, { - ComponentProps, - FunctionComponent, - MouseEvent, - ReactSVGElement, -} from 'react'; - -import { Overlay as OverlayComponent } from 'app/components/Overlay'; -import { useOvermind } from 'app/overmind'; - -import { Arrow, Container, OrderName } from './elements'; -import { FIELD_TO_NAME } from './FieldToName'; -import { Overlay } from './Overlay'; - -type Props = Pick, 'hideOrder'>; -export const SortOptions: FunctionComponent = ({ hideOrder }) => { - const { - actions: { - dashboard: { orderByChanged }, - }, - state: { - dashboard: { - orderBy: { field, order }, - }, - }, - } = useOvermind(); - - const toggleSort = (event: MouseEvent) => { - event.preventDefault(); - - orderByChanged({ - field, - order: order === 'asc' ? 'desc' : 'asc', - }); - }; - - return ( - - {open => ( - - Sort by {FIELD_TO_NAME[field]} - - - )} - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/elements.ts b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/elements.ts deleted file mode 100644 index 3e2789fcad0..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/elements.ts +++ /dev/null @@ -1,13 +0,0 @@ -import styled from 'styled-components'; - -export const Container = styled.div` - display: flex; - margin-right: 2rem; - align-items: center; - - @media (max-width: 1000px) { - position: relative; - right: 0; - margin-top: 1rem; - } -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/index.tsx b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/index.tsx deleted file mode 100644 index a2304d7b7e4..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/index.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React, { ComponentProps, FunctionComponent } from 'react'; - -import { FilterOptions } from './FilterOptions'; -import { SortOptions } from './SortOptions'; - -import { Container } from './elements'; - -type Props = Pick< - ComponentProps, - 'hideFilters' | 'possibleTemplates' -> & - Partial, 'hideOrder'>>; -export const Filters: FunctionComponent = ({ - hideFilters, - hideOrder, - possibleTemplates, -}) => ( - - - - - -); diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/index.tsx b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/index.tsx deleted file mode 100644 index f8174748511..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/index.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import React, { ComponentProps, ComponentType, FunctionComponent } from 'react'; - -import { DelayedAnimation } from 'app/components/DelayedAnimation'; -import { useOvermind } from 'app/overmind'; - -import { Container, HeaderContainer, HeaderTitle } from '../elements'; -import { SandboxGrid } from '../SandboxGrid'; - -import { DashboardActions } from './Actions'; -import { Filters } from './Filters'; - -type Props = { - Header: ComponentType | string; - isLoading?: boolean; - SubHeader?: ComponentType; -} & Pick, 'actions'> & - Pick< - ComponentProps, - 'ExtraElement' | 'page' | 'sandboxes' - > & - Pick< - ComponentProps, - 'hideFilters' | 'hideOrder' | 'possibleTemplates' - >; -export const Content: FunctionComponent = ({ - actions: dashboardActions, - ExtraElement, - Header, - hideFilters, - hideOrder, - isLoading = false, - page, - possibleTemplates, - sandboxes, - SubHeader, -}) => { - const { state, actions } = useOvermind(); - - return ( - - - - {Header} - - {sandboxes && !isLoading && ( - - {sandboxes.length} - - )} - - - - - - - - {SubHeader} - - {isLoading ? ( - - Fetching Sandboxes... - - ) : ( - - )} -
- ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/utils.ts b/packages/app/src/app/pages/Dashboard/Content/Sandboxes/utils.ts deleted file mode 100644 index 632eb3a432c..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Sandboxes/utils.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { uniqBy } from 'lodash-es'; -import getDefinition from '@codesandbox/common/lib/templates'; - -export function getPossibleTemplates(sandboxes: any[]) { - return uniqBy( - sandboxes.map(x => { - const templateId = x.source?.template; - const template = getDefinition(templateId); - - return { - id: templateId, - color: template.color, - name: template.name, - niceName: template.niceName, - }; - }), - template => template.id - ); -} diff --git a/packages/app/src/app/pages/Dashboard/Content/Selection/index.js b/packages/app/src/app/pages/Dashboard/Content/Selection/index.js deleted file mode 100644 index 2465a86ff42..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/Selection/index.js +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react'; -import styled from 'styled-components'; - -import { Spring, animated } from 'react-spring/renderprops'; - -const Container = styled(animated.div)` - position: fixed; - border: 1px solid ${props => props.theme.secondary}; - background-color: ${props => props.theme.secondary.clearer(0.5)}; - pointer-events: none; -`; - -export function getBounds(startX, startY, endX, endY) { - const top = startY > endY ? endY : startY; - const left = startX > endX ? endX : startX; - const width = startX > endX ? startX - endX : endX - startX; - const height = startY > endY ? startY - endY : endY - startY; - - return { - top, - height, - left, - width, - }; -} - -export const Selection = ({ startX, startY, endX, endY }) => { - const { top, height, left, width } = getBounds(startX, startY, endX, endY); - - return ( - - {style => } - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/elements.js b/packages/app/src/app/pages/Dashboard/Content/elements.js deleted file mode 100644 index b06c51acbd3..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/elements.js +++ /dev/null @@ -1,41 +0,0 @@ -import styled from 'styled-components'; - -export const Container = styled.div` - width: 100%; - height: 100%; - box-sizing: border-box; - padding-left: 2rem; -`; - -export const HeaderContainer = styled.div` - position: relative; - display: flex; - font-size: 1.25rem; - color: white; - - @media (max-width: 768px) { - margin-left: 1rem; - } -`; - -export const Description = styled.p` - font-size: 1rem; - width: 100%; - font-weight: 600; - color: ${props => - props.theme.light ? 'rgba(0, 0, 0, 0.7)' : 'rgba(255, 255, 255, 0.7)'}; - - line-height: 1.6; - - @media (max-width: 768px) { - margin-left: 1rem; - } -`; - -export const HeaderTitle = styled.div` - display: flex; - flex: 1; - width: 100%; - vertical-align: middle; - align-items: center; -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/index.js b/packages/app/src/app/pages/Dashboard/Content/index.js deleted file mode 100644 index b3cf3c93ae2..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/index.js +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react'; -import { Route, Switch, withRouter, Redirect } from 'react-router-dom'; - -import codesandbox from '@codesandbox/components/lib/themes/codesandbox.json'; -import { ThemeProvider } from '@codesandbox/components'; -import { dashboard } from '@codesandbox/common/lib/utils/url-generator'; -import { useOvermind } from 'app/overmind'; - -import { NEW_DASHBOARD } from '@codesandbox/common/lib/utils/feature-flags'; -import { RecentSandboxes } from './routes/RecentSandboxes'; -import PathedSandboxes from './routes/PathedSandboxes'; -import { Templates } from './routes/Templates'; -import DeletedSandboxes from './routes/DeletedSandboxes'; -import SearchSandboxes from './routes/SearchSandboxes'; -import CreateTeam from './routes/CreateTeam'; -import TeamView from './routes/TeamView'; - -const Content = () => { - const { state } = useOvermind(); - - return ( - - - - - - - - - - - - - {NEW_DASHBOARD ? ( - - ) : ( - - )} - - - ); -}; - -export default withRouter(Content); diff --git a/packages/app/src/app/pages/NewDashboard/Content/index.tsx b/packages/app/src/app/pages/Dashboard/Content/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/index.tsx rename to packages/app/src/app/pages/Dashboard/Content/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/All/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/All/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/All/index.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/All/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/All/useFilteredItems.ts b/packages/app/src/app/pages/Dashboard/Content/routes/All/useFilteredItems.ts similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/All/useFilteredItems.ts rename to packages/app/src/app/pages/Dashboard/Content/routes/All/useFilteredItems.ts diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/CreateTeam/Plan/elements.js b/packages/app/src/app/pages/Dashboard/Content/routes/CreateTeam/Plan/elements.js deleted file mode 100644 index b0248823f62..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/CreateTeam/Plan/elements.js +++ /dev/null @@ -1,71 +0,0 @@ -import styled, { css } from 'styled-components'; - -export const Container = styled.div` - transition: 0.3s ease border-color; - border-radius: 4px; - padding: 1rem; - border: 2px solid rgba(0, 0, 0, 0.3); - color: rgba(255, 255, 255, 0.8); - - background-color: ${props => props.theme.background}; - margin-bottom: 1.5rem; - - cursor: pointer; - - ${props => - props.selected - ? css` - border-color: ${props.theme.shySecondary}; - ` - : css` - &:hover { - border-color: ${props.theme.shySecondary.clearer(0.6)}; - } - `}; -`; - -export const Name = styled.h1` - font-size: 1.125rem; - font-weight: 600; - margin-top: 0; - margin-bottom: 1rem; - color: white; -`; - -export const Points = styled.div` - font-size: 1rem; - font-weight: 600; - line-height: 1.6; - color: ${props => - props.theme.light ? 'rgba(0, 0, 0, 0.7)' : 'rgba(255, 255, 255, 0.7)'}; -`; - -export const CheckBox = styled.span` - ${props => - props.selected - ? css` - background: ${props.color} url('') no-repeat 50%/10px; - background-image: url("data:image/svg+xml;utf8,"); - ` - : css` - background: rgba(0, 0, 0, 0.3) url('') no-repeat 50%/10px; - background-image: url("data:image/svg+xml;utf8, ( - - {name} - - {points.map((point, i) => ( -
- -
{point}
-
- ))} - - -); diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/CreateTeam/elements.js b/packages/app/src/app/pages/Dashboard/Content/routes/CreateTeam/elements.js deleted file mode 100644 index db106805b97..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/CreateTeam/elements.js +++ /dev/null @@ -1,57 +0,0 @@ -import styled from 'styled-components'; - -export const Label = styled.label` - display: block; - font-weight: 600; - color: ${props => - props.theme.light ? 'rgba(0, 0, 0, 0.7)' : 'rgba(255, 255, 255, 0.7)'}; - margin-bottom: 0.5rem; - margin-top: 2rem; -`; - -export const ComingSoon = styled.div` - position: relative; - - &:hover { - .overlay { - opacity: 1; - } - } -`; - -export const Overlay = styled.div` - transition: 0.3s ease opacity; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - border-radius: 4px; - background-color: rgba(0, 0, 0, 0.5); - opacity: 0; - - padding: 2rem; - - display: flex; - justify-content: center; - - font-weight: 600; - font-size: 1.5rem; - - color: white; -`; - -export const PatronInfo = styled.div` - position: absolute; - left: 100%; - margin-left: 2rem; - width: 400px; -`; - -export const QuestionHeader = styled.h2` - font-size: 1.125rem; - font-weight: 600; - margin-top: 0.5rem; - margin-bottom: 1rem; - color: white; -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/CreateTeam/index.js b/packages/app/src/app/pages/Dashboard/Content/routes/CreateTeam/index.js deleted file mode 100644 index 7707c54f6e1..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/CreateTeam/index.js +++ /dev/null @@ -1,168 +0,0 @@ -import React from 'react'; -import { Mutation } from 'react-apollo'; - -import Input from '@codesandbox/common/lib/components/Input'; -import { Button } from '@codesandbox/common/lib/components/Button'; -import track from '@codesandbox/common/lib/utils/analytics'; -import history from 'app/utils/history'; -import { teamOverviewUrl } from '@codesandbox/common/lib/utils/url-generator'; -import { notificationState } from '@codesandbox/common/lib/utils/notifications'; -import { NotificationStatus } from '@codesandbox/notifications'; - -import { Container, Description, HeaderContainer } from '../../elements'; -import { - Label, - ComingSoon, - Overlay, - PatronInfo, - QuestionHeader, -} from './elements'; -import { CREATE_TEAM_MUTATION, TEAMS_QUERY } from '../../../queries'; - -import Plan from './Plan'; - -const FREE_POINTS = [ - 'Unlimited Users', - '20 Mb Static File Hosting per User', - 'Live Collaboration', -]; - -const PRO_POINTS = [ - 'Unlimited Users', - '500 Mb Static File Hosting per User', - 'Live Collaboration', - 'Team Invoices', - 'Private & Unlisted Sandboxes', -]; - -export default class CreateTeam extends React.PureComponent { - state = { inputValue: '' }; - - handleChange = e => { - this.setState({ inputValue: e.target.value }); - }; - - render() { - return ( - - Create a Team - - - Make collaboration easy by creating teams. Teams allow you to create - and edit sandboxes that are shared between you and your team members. - - - - {mutate => { - const submit = e => { - e.preventDefault(); - e.stopPropagation(); - const name = this.state.inputValue; - - track('Team - Create Team'); - - mutate({ - variables: { - name, - }, - optimisticResponse: { - __typename: 'Mutation', - createTeam: { - __typename: 'Team', - id: 'new-team', - name, - }, - }, - update: (proxy, { data: { createTeam } }) => { - // Read the data from our cache for this query. - const d = proxy.readQuery({ - query: TEAMS_QUERY, - }); - - // Add our team from the mutation to the end. - d.me.teams.push(createTeam); - // Write our data back to the cache. - proxy.writeQuery({ - query: TEAMS_QUERY, - data: d, - }); - }, - }).then(({ data }) => { - notificationState.addNotification({ - message: `Successfully created team '${data.createTeam.name}'`, - status: NotificationStatus.SUCCESS, - }); - - history.push(teamOverviewUrl(data.createTeam.id)); - }); - }; - - return ( -
- - - - - - - - - - What if I{"'"}m a{' '} - - Pro - - ? - - - - You can benefit from all Pro features. This means that you - can create unlimited private and unlisted sandboxes as a - Pro in your team. -
-
- When we release Team Pro it will be required to have a Pro - subscription to get the Pro functionality. -
-
- - - Coming Soon -
- -
-
- -
- - - - ); - }} -
-
- ); - } -} diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Deleted/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Deleted/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Deleted/index.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Deleted/index.tsx diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/DeletedSandboxes/index.js b/packages/app/src/app/pages/Dashboard/Content/routes/DeletedSandboxes/index.js deleted file mode 100644 index 589c9e5c29c..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/DeletedSandboxes/index.js +++ /dev/null @@ -1,76 +0,0 @@ -import { Observer } from 'app/overmind'; -import React from 'react'; -import { Query } from 'react-apollo'; -import Helmet from 'react-helmet'; -import RemoveIcon from 'react-icons/lib/md/highlight-remove'; - -import { DELETED_SANDBOXES_CONTENT_QUERY } from '../../../queries'; -import { Content as Sandboxes } from '../../Sandboxes'; -import { getPossibleTemplates } from '../../Sandboxes/utils'; - -const DeletedSandboxes = () => ( - <> - - Deleted Sandboxes - CodeSandbox - - - {({ loading, error, data }) => ( - - {({ state, actions }) => { - if (error) { - return
Error!
; - } - - const sandboxes = loading - ? [] - : (data && data.me && data.me.sandboxes) || []; - - const possibleTemplates = getPossibleTemplates(sandboxes); - - const orderedSandboxes = state.dashboard.getFilteredSandboxes( - sandboxes - ); - const trashSandboxIds = orderedSandboxes.map(i => i.id); - if ( - JSON.stringify(state.dashboard.trashSandboxIds) !== - JSON.stringify(trashSandboxIds) - ) { - actions.dashboard.setTrashSandboxes({ - sandboxIds: trashSandboxIds, - }); - } - - return ( - , - run: () => { - actions.modalOpened({ - modal: 'emptyTrash', - }); - }, - }, - ] - : [] - } - /> - ); - }} -
- )} -
- -); - -export default DeletedSandboxes; diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Drafts/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Drafts/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Drafts/index.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Drafts/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Home/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Home/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Home/index.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Home/index.tsx diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Folders.js b/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Folders.js deleted file mode 100644 index c7048de9a6b..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Folders.js +++ /dev/null @@ -1,54 +0,0 @@ -import React from 'react'; -import { withRouter } from 'react-router-dom'; -import FolderEntry from '../../../Sidebar/SandboxesItem/FolderEntry'; -import getChildCollections from '../../../utils/get-child-collections'; - -import { Folder, FoldersWrapper } from './elements'; - -const Folders = ({ loading, me, history, match: { params }, teamId }) => { - const getPath = name => (params.path ? `${params.path}/${name}` : '/' + name); - const getURL = name => - params.path - ? `${params.path}/${encodeURIComponent(name)}` - : '/' + encodeURIComponent(name); - - if (loading) return null; - - const { children, foldersByPath, folders } = getChildCollections( - me.collections, - (me.collection || {}).path - ); - - if (children.size === 0) return null; - - return ( - - {Array.from(children) - .sort() - .map(name => ( - - { - history.push(window.location.pathname + '/' + name); - }} - currentPath={window.location.pathname} - currentTeamId={teamId} - /> - - ))} - - ); -}; - -export default withRouter(Folders); diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Navigation/NavigationLink.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Navigation/NavigationLink.tsx deleted file mode 100644 index 41bf72ab2bb..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Navigation/NavigationLink.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React from 'react'; -import { DropTarget, ConnectDropTarget } from 'react-dnd'; -import { - entryTarget, - collectTarget, -} from '../../../../Sidebar/SandboxesItem/folder-drop-target'; -import { NavigationLink as StyledLink } from './elements'; - -interface ICollectedProps { - connectDropTarget: ConnectDropTarget; - isOver: boolean; -} - -interface IOwnProps { - teamId?: string; - name: string; - path: string; - splittedPath: string[]; - i: number; - // We need this to make drag & drop work - selectedSandboxes: string[]; -} - -type Props = ICollectedProps & IOwnProps; - -const Link: React.FC = ({ - teamId, - name, - path, - isOver, - splittedPath, - i, - connectDropTarget, -}) => - connectDropTarget( -
- - {name} - -
- ); - -// TODO: remove generic when entryTarget(DropTargetSpec) and collectTarget(DropTargetCollector) are typed -export const NavigationLink = DropTarget( - 'SANDBOX', - entryTarget, - collectTarget -)(Link); diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Navigation/elements.ts b/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Navigation/elements.ts deleted file mode 100644 index 33f70b16fa3..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Navigation/elements.ts +++ /dev/null @@ -1,46 +0,0 @@ -import styled, { css } from 'styled-components'; -import { Link } from 'react-router-dom'; - -export const Container = styled.div` - display: flex; - align-items: center; - position: relative; -`; - -// TODO: Use withoutProps utility from common once Follow Templates is merged -// to remove the DOM error for teamId prop -export const NavigationLink = styled(Link)<{ first?: string; last?: string }>` - transition: 0.3s ease color; - margin-right: 0.5rem; - text-decoration: none; - color: rgba(255, 255, 255, 0.6); - - &:hover { - color: white; - } - - &:last-child { - margin-right: 0; - } - - ${props => - props.first - ? css` - margin-left: 0; - ` - : css` - margin-left: 0.5rem; - `}; - - ${props => - props.last - ? css` - color: white; - ` - : css` - &::after { - content: '›'; - margin-left: 0.5rem; - } - `}; -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Navigation/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Navigation/index.tsx deleted file mode 100644 index b3d87291501..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/Navigation/index.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react'; -import { join } from 'path'; - -import { useOvermind } from 'app/overmind'; -import { Container } from './elements'; -import { NavigationLink } from './NavigationLink'; - -interface INavigationProps { - path: string; - teamId?: string; -} - -export const Navigation: React.FC = ({ path, teamId }) => { - const { state } = useOvermind(); - - const splittedPath = path === '/' ? [''] : path.split('/'); - - const paths = splittedPath.reduce((bases, next) => { - if (next === '') { - return [{ url: '/', name: teamId ? 'Team Sandboxes' : 'My Sandboxes' }]; - } - - const baseUrl = bases[bases.length - 1].url; - bases.push({ url: join(baseUrl, next), name: next }); - return bases; - }, []); - - return ( - - {paths.map(({ name, url }, i) => ( - - ))} - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/elements.js b/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/elements.js deleted file mode 100644 index f24e5e1b9ba..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/elements.js +++ /dev/null @@ -1,20 +0,0 @@ -import styled from 'styled-components'; - -export const Folder = styled.div` - min-width: 235px; - height: 40px; - display: flex; - align-items: center; - margin-right: 30px; - padding: 0 11px; - margin-bottom: 20px; - - background: #25282a; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); -`; - -export const FoldersWrapper = styled.section` - display: flex; - margin-top: 40px; - flex-wrap: wrap; -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/index.js b/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/index.js deleted file mode 100644 index 7110cd11761..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/index.js +++ /dev/null @@ -1,93 +0,0 @@ -import { basename } from 'path'; - -import { CreateNewSandboxButton } from 'app/components/CreateNewSandbox'; -import { Observer } from 'app/overmind'; -import React from 'react'; -import { Query } from 'react-apollo'; -import Helmet from 'react-helmet'; - -import { PATHED_SANDBOXES_CONTENT_QUERY } from '../../../queries'; -// import Folders from './Folders'; -import getMostUsedTemplate from '../../../utils/get-most-used-template'; -import { Content as Sandboxes } from '../../Sandboxes'; -import { getPossibleTemplates } from '../../Sandboxes/utils'; -import { Navigation } from './Navigation'; - -const PathedSandboxes = props => { - const path = '/' + decodeURIComponent(props.match.params.path || ''); - const { teamId } = props.match.params; - return ( - <> - - {basename(path) || 'Dashboard'} - CodeSandbox - - - {({ loading, error, data }) => ( - - {({ state }) => { - if (error) { - console.error(error); - return
Error!
; - } - - const sandboxes = - loading || !data.me || !data.me.collection - ? [] - : data.me.collection.sandboxes; - - const possibleTemplates = getPossibleTemplates(sandboxes); - - // We want to hide all templates - // TODO: make this a query variable for graphql and move the logic to the server - const noTemplateSandboxes = sandboxes.filter( - s => !s.customTemplate - ); - const orderedSandboxes = state.dashboard.getFilteredSandboxes( - noTemplateSandboxes - ); - - let mostUsedTemplate = null; - if (!loading) { - try { - mostUsedTemplate = getMostUsedTemplate(sandboxes); - } catch (e) { - // Not critical - } - } - - return ( - ( - - )} - isLoading={loading} - possibleTemplates={possibleTemplates} - Header={} - // Fix React Virtualized First - // SubHeader={ - // - // } - sandboxes={orderedSandboxes} - /> - ); - }} -
- )} -
- - ); -}; - -export default PathedSandboxes; diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Recent/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Recent/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Recent/index.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Recent/index.tsx diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/RecentSandboxes/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/RecentSandboxes/index.tsx deleted file mode 100644 index 91471d7b2eb..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/RecentSandboxes/index.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React from 'react'; -import { Helmet } from 'react-helmet'; -import { useQuery } from '@apollo/react-hooks'; - -import { useOvermind } from 'app/overmind'; -import { CreateNewSandboxButton } from 'app/components/CreateNewSandbox'; -import { - RecentSandboxesQuery, - RecentSandboxesQueryVariables, -} from 'app/graphql/types'; -import getMostUsedTemplate from '../../../utils/get-most-used-template'; -import { Content as Sandboxes } from '../../Sandboxes'; -import { RECENT_SANDBOXES_CONTENT_QUERY } from '../../../queries'; - -export const RecentSandboxes = () => { - const { state } = useOvermind(); - const { loading, error, data } = useQuery< - RecentSandboxesQuery, - RecentSandboxesQueryVariables - >(RECENT_SANDBOXES_CONTENT_QUERY, { - variables: { - orderField: state.dashboard.orderBy.field, - // @ts-ignore - orderDirection: state.dashboard.orderBy.order.toUpperCase(), - }, - }); - - if (error) { - return
Error!
; - } - - const sandboxes = loading ? [] : (data && data.me && data.me.sandboxes) || []; - - let mostUsedTemplate = null; - try { - mostUsedTemplate = getMostUsedTemplate(sandboxes); - } catch (e) { - // Not critical - } - - // We want to hide all templates - // TODO: make this a query variable for graphql and move the logic to the server - const noTemplateSandboxes = sandboxes.filter(s => !s.customTemplate); - return ( - <> - - Recent Sandboxes - CodeSandbox - - ( - - )} - hideFilters - sandboxes={noTemplateSandboxes} - page="recent" - /> - - ); -}; diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Repositories/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Repositories/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Repositories/index.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Repositories/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Repositories/useFilteredItems.ts b/packages/app/src/app/pages/Dashboard/Content/routes/Repositories/useFilteredItems.ts similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Repositories/useFilteredItems.ts rename to packages/app/src/app/pages/Dashboard/Content/routes/Repositories/useFilteredItems.ts diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Search/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Search/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Search/index.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Search/index.tsx diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/SearchSandboxes/index.js b/packages/app/src/app/pages/Dashboard/Content/routes/SearchSandboxes/index.js deleted file mode 100644 index 71acdb79d7d..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/SearchSandboxes/index.js +++ /dev/null @@ -1,87 +0,0 @@ -import { Observer } from 'app/overmind'; -import Fuse from 'fuse.js'; -import React from 'react'; -import { Query } from 'react-apollo'; -import Helmet from 'react-helmet'; - -import { SEARCH_SANDBOXES_QUERY } from '../../../queries'; -import { Content as Sandboxes } from '../../Sandboxes'; -import { getPossibleTemplates } from '../../Sandboxes/utils'; - -let lastSandboxes = null; -let searchIndex = null; - -const SearchSandboxes = () => ( - - {({ loading, error, data }) => ( - - {({ state }) => { - if (error) { - return
Error!
; - } - - const { search } = state.dashboard.filters; - let sandboxes = data && data.me && data.me.sandboxes; - if ( - sandboxes && - (lastSandboxes === null || lastSandboxes !== sandboxes) - ) { - searchIndex = new Fuse(sandboxes, { - threshold: 0.1, - distance: 1000, - keys: [ - { name: 'title', weight: 0.4 }, - { name: 'description', weight: 0.2 }, - { name: 'alias', weight: 0.2 }, - { name: 'source.template', weight: 0.1 }, - { name: 'id', weight: 0.1 }, - ], - }); - - lastSandboxes = sandboxes; - } - - if (searchIndex && search) { - sandboxes = searchIndex.search(search); - } - - const Header = - search && sandboxes - ? `${sandboxes.length} search results for '${search}'` - : 'Search results for all sandboxes'; - - let possibleTemplates = []; - if (sandboxes) { - possibleTemplates = getPossibleTemplates(sandboxes); - - sandboxes = state.dashboard - .getFilteredSandboxes(sandboxes) - .filter(x => !x.customTemplate); - } - - return ( - <> - - - {search - ? `Search: '${search}' - CodeSandbox` - : 'Search - CodeSandbox'} - - - - - ); - }} -
- )} -
-); - -export default SearchSandboxes; diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Settings/Invite.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Settings/Invite.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Settings/Invite.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Settings/Invite.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Settings/NewTeam.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Settings/NewTeam.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Settings/NewTeam.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Settings/NewTeam.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Settings/TeamSettings.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Settings/TeamSettings.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Settings/TeamSettings.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Settings/TeamSettings.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Settings/UserSettings.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Settings/UserSettings.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Settings/UserSettings.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Settings/UserSettings.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Settings/components/MemberList.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Settings/components/MemberList.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Settings/components/MemberList.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Settings/components/MemberList.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Settings/components/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Settings/components/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Settings/components/index.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Settings/components/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Settings/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Settings/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Settings/index.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Settings/index.tsx diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/AddTeamMember/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/AddTeamMember/index.tsx deleted file mode 100644 index 5bafe73a56c..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/AddTeamMember/index.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import React from 'react'; -import styled from 'styled-components'; - -import { Button } from '@codesandbox/components'; - -import { useMutation } from '@apollo/react-hooks'; - -import track from '@codesandbox/common/lib/utils/analytics'; - -import { UserSearchInput } from 'app/components/UserSearchInput'; - -import { useOvermind } from 'app/overmind'; -import { INVITE_TO_TEAM, INVITE_TO_TEAM_VIA_EMAIL } from '../../../../queries'; -import { IAddTeamMemberProps, IMutationVariables } from './types'; - -const ErrorMessage = styled.div` - color: ${props => props.theme.red}; - font-weight: 600; - font-size: 0.875rem; - margin-bottom: 0.5rem; -`; - -export const AddTeamMember: React.FC = ({ teamId }) => { - const { actions } = useOvermind(); - const [inviteToTeam] = useMutation(INVITE_TO_TEAM); - const [inviteToTeamViaEmail] = useMutation(INVITE_TO_TEAM_VIA_EMAIL); - - const [loading, setLoading] = React.useState(false); - const [error, setError] = React.useState< - null | (Error & { graphQLErrors: Error[] }) - >(null); - const [inviteValue, setInviteValue] = React.useState(''); - - const submit: React.FormEventHandler = async e => { - e.preventDefault(); - e.stopPropagation(); - setLoading(true); - setError(null); - - try { - const isEmail = inviteValue.includes('@'); - - track('Team - Add Member', { email: isEmail }); - - // We don't enable email for now for privacy reasons - - const variables: IMutationVariables = { teamId }; - - const inviteVar = inviteValue; - setInviteValue(''); - - if (isEmail) { - variables.email = inviteVar; - await inviteToTeamViaEmail({ - variables, - }); - } else { - variables.username = inviteVar; - await inviteToTeam({ - variables, - }); - } - - actions.notificationAdded({ - title: `${inviteVar} has been invited!`, - notificationType: 'success', - }); - } catch (err) { - setError(err); - } finally { - setLoading(false); - } - }; - - const errorMessage = - error && - error.graphQLErrors && - error.graphQLErrors[0] && - error.graphQLErrors[0].message; - - return ( - <> - {errorMessage && {errorMessage}} -
- { - setInviteValue(val); - }} - /> - - - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/AddTeamMember/types.ts b/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/AddTeamMember/types.ts deleted file mode 100644 index f7664a9e328..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/AddTeamMember/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -type TeamId = string; - -export interface IAddTeamMemberProps { - teamId: TeamId; -} - -export interface IMutationVariables { - teamId: TeamId; - email?: string; - username?: string; -} diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/InviteLink/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/InviteLink/index.tsx deleted file mode 100644 index 2cce8083e6a..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/InviteLink/index.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; - -import { Button, Stack, Input } from '@codesandbox/components'; -import { teamInviteLink } from '@codesandbox/common/lib/utils/url-generator'; - -import { useOvermind } from 'app/overmind'; -import { IInviteLinkProps } from './types'; - -export const InviteLink: React.FC = ({ inviteToken }) => { - const { effects } = useOvermind(); - - const [isCopied, setIsCopied] = React.useState(false); - - const inviteLink = teamInviteLink(inviteToken); - - const copyLink = () => { - setIsCopied(true); - effects.browser.copyToClipboard(inviteLink); - - setTimeout(() => { - setIsCopied(false); - }, 2000); - }; - - return ( - - e.target.select()} value={inviteLink} /> - - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/InviteLink/types.ts b/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/InviteLink/types.ts deleted file mode 100644 index f8ec1975385..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/InviteLink/types.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface IInviteLinkProps { - inviteToken: string; -} diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/RemoveTeamMember/index.js b/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/RemoveTeamMember/index.js deleted file mode 100644 index d2bcbfafb8a..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/RemoveTeamMember/index.js +++ /dev/null @@ -1,91 +0,0 @@ -import React from 'react'; -import { Mutation } from 'react-apollo'; - -import Tooltip from '@codesandbox/common/lib/components/Tooltip'; -import history from 'app/utils/history'; -import { dashboardUrl } from '@codesandbox/common/lib/utils/url-generator'; -import { NotificationStatus } from '@codesandbox/notifications'; -import { notificationState } from '@codesandbox/common/lib/utils/notifications'; - -import { REMOVE_FROM_TEAM, LEAVE_TEAM } from '../../../../queries'; - -import { StyledCrossIcon } from '../elements'; - -export const RemoveTeamMember = ({ - creatorId, - currentUserId, - userId, - totalMemberSize, - teamId, - name, -}) => { - if (creatorId === userId && totalMemberSize > 1) { - return ( -
- Owner -
- ); - } - - const isCreator = currentUserId === creatorId; - const isOwnUser = userId === currentUserId; - - if (isCreator || isOwnUser) { - return ( - - { - notificationState.addNotification({ - message: isOwnUser - ? 'Successfully left the team' - : 'Successfully removed from team', - status: NotificationStatus.SUCCESS, - }); - - history.push(dashboardUrl()); - }} - > - {(mutate, { loading }) => ( - { - let confirmation = true; - if (isOwnUser && isCreator) { - // eslint-disable-next-line no-alert - confirmation = confirm( - "Are you sure you want to leave? You won't be able to access the team again." - ); - } - if (confirmation) { - mutate(); - } - }} - /> - )} - - - ); - } - - return false; -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/elements.js b/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/elements.js deleted file mode 100644 index 54e8e503f6f..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/elements.js +++ /dev/null @@ -1,61 +0,0 @@ -import styled from 'styled-components'; -import CrossIcon from 'react-icons/lib/md/clear'; -import EditIcon from 'react-icons/lib/go/pencil'; - -export const TeamContainer = styled.div` - display: flex; - width: 100%; - - @media (max-width: 900px) { - flex-direction: column; - } -`; - -export const Section = styled.div` - flex: 1; - width: 100%; - - margin-right: 2rem; -`; - -export const Members = styled.div` - margin-top: 1rem; - - @media (max-width: 768px) { - margin-left: 1rem; - } -`; - -export const MemberHeader = styled.div` - margin: 1.5rem 0; - margin-bottom: 0.5rem; - font-size: 0.875rem; - - font-weight: 600; - color: rgba(255, 255, 255, 0.6); -`; - -export const StyledCrossIcon = styled(CrossIcon)` - transition: 0.3s ease color; - color: white; - cursor: pointer; - - &:hover { - color: ${props => props.theme.red}; - } -`; - -export const StyledEditIcon = styled(EditIcon)` - transition: 0.3s ease color; - vertical-align: middle; - font-size: 1rem; - margin-bottom: 5px; - margin-left: 0.75rem; - color: ${props => - props.theme.light ? 'rgba(0, 0, 0, 0.7)' : 'rgba(255, 255, 255, 0.7)'}; - cursor: pointer; - - &:hover { - color: white; - } -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/index.js b/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/index.js deleted file mode 100644 index 45043d48a46..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/TeamView/index.js +++ /dev/null @@ -1,340 +0,0 @@ -import AutosizeTextArea from '@codesandbox/common/lib/components/AutosizeTextArea'; -import { Button, Input } from '@codesandbox/components'; -import Margin from '@codesandbox/common/lib/components/spacing/Margin'; -import { UserWithAvatar } from '@codesandbox/common/lib/components/UserWithAvatar'; -import track from '@codesandbox/common/lib/utils/analytics'; -import { Observer } from 'app/overmind'; -import { sortBy } from 'lodash-es'; -import React from 'react'; -import { Mutation, Query } from 'react-apollo'; -import Helmet from 'react-helmet'; - -import { - REVOKE_TEAM_INVITATION, - SET_TEAM_DESCRIPTION, - SET_TEAM_NAME, - TEAM_QUERY, -} from '../../../queries'; -import { Container, Description, HeaderContainer } from '../../elements'; -import { AddTeamMember } from './AddTeamMember'; -import { - MemberHeader, - Members, - Section, - StyledEditIcon, - TeamContainer, -} from './elements'; -import { RemoveTeamMember } from './RemoveTeamMember'; -import { InviteLink } from './InviteLink'; - -const User = ({ user, rightElement }) => ( -
-
- -
- - {rightElement} -
-); - -class TeamView extends React.PureComponent { - state = { - editingDescription: false, - editingName: false, - }; - - render() { - const { teamId } = this.props.match.params; - - return ( - - - {({ data, loading, error }) => ( - - {({ state }) => { - const currentUser = state.user; - if (loading || error) { - return null; - } - - const description = - data.me.team.description || - `This is a description for your team. You can change this description and invite people to the team so they can edit the sandboxes of this team.`; - - return ( - - - {data.me.team.name} - CodeSandbox - -
- - {this.state.editingName ? ( - - {(mutate, { loading: nameLoading }) => { - let input = null; - - const stopEditing = () => { - this.setState({ editingName: false }); - }; - const submit = e => { - e.preventDefault(); - e.stopPropagation(); - - mutate({ - variables: { - teamId, - name: input.value, - }, - }).then(stopEditing); - }; - - return ( -
-
- { - input = node; - if (node) { - node.focus(); - } - }} - onBlur={() => { - stopEditing(); - }} - style={{ - padding: '.5em', - lineHeight: '1.6', - }} - defaultValue={data.me.team.name} - /> -
-
- ); - }} -
- ) : ( -
- {data.me.team.name}{' '} - { - this.setState(currentState => ({ - editingName: !currentState.editingName, - })); - }} - /> -
- )} -
- - {this.state.editingDescription ? ( - - {(mutate, { loading: descriptionLoading }) => { - let input = null; - - const stopEditing = () => { - this.setState({ editingDescription: false }); - }; - const submit = e => { - e.preventDefault(); - e.stopPropagation(); - - mutate({ - variables: { - teamId, - description: input.value, - }, - }).then(stopEditing); - }; - - return ( -
-
- { - input = node; - }} - multiline - style={{ - padding: '.5em', - lineHeight: '1.6', - }} - defaultValue={description} - /> -
-
- - -
-
- ); - }} -
- ) : ( -
- {description} - - { - this.setState(currentState => ({ - editingDescription: !currentState.editingDescription, - })); - }} - /> -
- )} -
-
-
- Team Members - - - {sortBy( - data.me.team.users, - u => u.name || u.username - ).map(user => ( - - } - /> - ))} - - {data.me.team.invitees && - data.me.team.invitees.length > 0 && ( - <> - Invited Members - - {data.me.team.invitees.map(user => ( - - {(mutate, { loading: revokeLoading }) => { - track('Team - Revoke Invitation'); - - const handleClick = () => - mutate({ - variables: { userId: user.id, teamId }, - }); - - return ( - - -
- } - /> - ); - }} - - ))} - - )} - - - - - - - - - - - ); - }} - - )} - - - ); - } -} - -export default TeamView; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/BookmarkedTemplates/elements.ts b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/BookmarkedTemplates/elements.ts deleted file mode 100644 index c6b5b49635f..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/BookmarkedTemplates/elements.ts +++ /dev/null @@ -1,9 +0,0 @@ -import styled from 'styled-components'; - -export const ButtonContainer = styled.div` - display: flex; - - a:not(:last-child) { - margin-right: 1rem; - } -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/BookmarkedTemplates/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/BookmarkedTemplates/index.tsx deleted file mode 100644 index a81ae3b7db0..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/BookmarkedTemplates/index.tsx +++ /dev/null @@ -1,161 +0,0 @@ -import React, { useEffect } from 'react'; -import { sortBy } from 'lodash-es'; -import { useQuery, useMutation, useApolloClient } from '@apollo/react-hooks'; -import { DelayedAnimation } from 'app/components/DelayedAnimation'; -import { Button } from '@codesandbox/common/lib/components/Button'; -import { sandboxUrl } from '@codesandbox/common/lib/utils/url-generator'; -import history from 'app/utils/history'; -import track from '@codesandbox/common/lib/utils/analytics'; -import { ContextMenu } from 'app/components/ContextMenu'; -import CustomTemplate from '@codesandbox/common/lib/components/CustomTemplate'; -import { getSandboxName } from '@codesandbox/common/lib/utils/get-sandbox-name'; -import { LIST_BOOKMARKED_TEMPLATES_QUERY } from 'app/components/CreateNewSandbox/queries'; -import { - UnbookmarkTemplateFromDashboardMutation, - UnbookmarkTemplateFromDashboardMutationVariables, - ListPersonalBookmarkedTemplatesQuery, -} from 'app/graphql/types'; -import { useOvermind } from 'app/overmind'; -import { ButtonContainer } from './elements'; - -import { Grid, EmptyTitle } from '../elements'; -import { Navigation } from '../Navigation'; -import { UNBOOKMARK_TEMPLATE_FROM_DASHBOARD } from './mutations'; - -type BookmarkedTemplatesProps = { teamId?: string }; - -export const BookmarkedTemplates = (props: BookmarkedTemplatesProps) => { - const { teamId } = props; - - const { actions } = useOvermind(); - - const { loading, error, data } = useQuery< - ListPersonalBookmarkedTemplatesQuery - >(LIST_BOOKMARKED_TEMPLATES_QUERY); - const client = useApolloClient(); - const [unBookmark] = useMutation< - UnbookmarkTemplateFromDashboardMutation, - UnbookmarkTemplateFromDashboardMutationVariables - >(UNBOOKMARK_TEMPLATE_FROM_DASHBOARD, { - onCompleted({ unbookmarkTemplate: unbookmarkMutation }) { - const newTemplates = data.me.bookmarkedTemplates.filter( - template => template.id !== unbookmarkMutation.id - ); - client.writeData({ - data: { - ...data, - me: { - ...data.me, - bookmarkedTemplates: newTemplates, - }, - }, - }); - }, - }); - - useEffect(() => { - document.title = `${ - teamId ? 'Team' : 'My' - } Bookmarked Templates - CodeSandbox`; - }, [teamId]); - - const sortedTemplates = React.useMemo(() => { - if (data && data.me) { - if (teamId) { - const team = data.me.teams.find(t => t.id === teamId); - return team.bookmarkedTemplates; - } - - return data.me.bookmarkedTemplates; - } - - return undefined; - }, [teamId, data]); - - if (error) { - console.error(error); - return
Error!
; - } - - if (loading || !sortedTemplates) { - return ( - - Fetching Templates... - - ); - } - const orderedTemplates = sortBy(sortedTemplates, template => - getSandboxName(template.sandbox).toLowerCase() - ); - - return ( - <> - - {!orderedTemplates.length && ( -
- -

- You don{"'"}t have any bookmarked templates yet. You can discover - new templates on Template Universe! -

- - - - -
-
- )} - - {orderedTemplates.map((template, i) => ( - { - track('Template - Unbookmarked', { source: 'Context Menu' }); - if (teamId) { - unBookmark({ - variables: { teamId, template: template.id }, - }); - } else { - unBookmark({ - variables: { - template: template.id, - teamId: undefined, - }, - }); - } - return true; - }, - }, - ]} - key={template.id} - > - history.push(sandboxUrl(template.sandbox))} - /> - - ))} - - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/BookmarkedTemplates/mutations.ts b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/BookmarkedTemplates/mutations.ts deleted file mode 100644 index 42954737f41..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/BookmarkedTemplates/mutations.ts +++ /dev/null @@ -1,23 +0,0 @@ -import gql from 'graphql-tag'; - -export const UNBOOKMARK_TEMPLATE_FROM_DASHBOARD = gql` - mutation unbookmarkTemplateFromDashboard($template: ID!, $teamId: ID) { - unbookmarkTemplate(templateId: $template, teamId: $teamId) { - id - bookmarked { - isBookmarked - entity { - __typename - ... on User { - id - name: username - } - ... on Team { - id - name - } - } - } - } - } -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/Navigation/Navigation.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/Navigation/Navigation.tsx deleted file mode 100644 index 045693a8e3f..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/Navigation/Navigation.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; -import { Container, NavigationTitle, Number } from './elements'; - -interface INavigationProps { - teamId?: string; - number?: number; - bookmarked?: boolean; -} - -export const Navigation = ({ - teamId, - number, - bookmarked, -}: INavigationProps) => ( - - {bookmarked ? ( - - {teamId ? 'Bookmarked Templates' : 'Bookmarked Templates'} - - ) : ( - - {teamId ? 'Team Templates' : 'My Templates'} - - )} - - {number != null && {number}} - -); diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/Navigation/elements.ts b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/Navigation/elements.ts deleted file mode 100644 index 1697cf31ed9..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/Navigation/elements.ts +++ /dev/null @@ -1,31 +0,0 @@ -import styled from 'styled-components'; - -export const Container = styled.div` - position: relative; - display: flex; - align-items: center; -`; - -export const NavigationTitle = styled.h2` - display: inline-flex; - margin-right: 0.5rem; - text-decoration: none; - transition: 0.3s ease color; - font-size: 1.25rem; - margin-left: 0; - color: white; - margin-top: 0; - margin-bottom: 0; - font-weight: 400; - - &:last-child { - margin-right: 0; - } -`; - -export const Number = styled.span` - font-size: 1rem; - font-weight: 600; - color: rgba(255, 255, 255, 0.6); - margin-left: 0.5rem; -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/Navigation/index.ts b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/Navigation/index.ts deleted file mode 100644 index 61f39d15c97..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/Navigation/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Navigation } from './Navigation'; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/OwnedTemplates/OwnedTemplates.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/OwnedTemplates/OwnedTemplates.tsx deleted file mode 100644 index 74649651ddf..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/OwnedTemplates/OwnedTemplates.tsx +++ /dev/null @@ -1,139 +0,0 @@ -import React from 'react'; -import { sortBy } from 'lodash-es'; -import { useQuery } from '@apollo/react-hooks'; - -import { DelayedAnimation } from 'app/components/DelayedAnimation'; -import { ContextMenu } from 'app/components/ContextMenu'; -import { useOvermind } from 'app/overmind'; -import history from 'app/utils/history'; -import track from '@codesandbox/common/lib/utils/analytics'; -import theme from '@codesandbox/common/lib/theme'; -import { sandboxUrl } from '@codesandbox/common/lib/utils/url-generator'; -import CustomTemplate from '@codesandbox/common/lib/components/CustomTemplate'; -import { getSandboxName } from '@codesandbox/common/lib/utils/get-sandbox-name'; -import { - LIST_OWNED_TEMPLATES, - unmakeTemplates, -} from 'app/components/CreateNewSandbox/queries'; -import { - ListTemplatesQuery, - ListTemplatesQueryVariables, -} from 'app/graphql/types'; -import { Grid, EmptyTitle } from '../elements'; -import { Navigation } from '../Navigation'; - -type OwnedTemplatesProps = { teamId?: string }; - -export const OwnedTemplates = (props: OwnedTemplatesProps) => { - const { - actions: { - dashboard: { deleteTemplate }, - }, - effects: { - browser: { copyToClipboard }, - }, - } = useOvermind(); - const { teamId } = props; - const { loading, error, data, refetch } = useQuery< - ListTemplatesQuery, - ListTemplatesQueryVariables - >(LIST_OWNED_TEMPLATES, { - variables: { showAll: false }, - }); - - if (error) { - console.error(error); - return
Error!
; - } - - if (loading) { - return ( - - Fetching Templates... - - ); - } - - const templatesToUse = teamId - ? data.me.teams.find(t => t.id === teamId)?.templates - : data.me.templates; - - const sortedTemplates = sortBy(templatesToUse, template => - getSandboxName(template.sandbox).toLowerCase() - ); - - return ( - <> - - {!sortedTemplates.length && ( -
- -

- You have not created any templates yet. You can create a template - by dragging a sandbox from {'"'}My Sandboxes{'"'} to here or by - clicking {'"'}Create Template{'"'} from the editor. -

- You can learn more about templates{' '} - - here - - . -
-
- )} - - {sortedTemplates.map((template, i) => ( - { - track('Template - Removed', { source: 'Context Menu' }); - unmakeTemplates([template.sandbox.id]); - return true; - }, - }, - { - title: 'Copy Template Link', - action: () => { - copyToClipboard( - `https://codesandbox.io${sandboxUrl(template.sandbox)}` - ); - return true; - }, - }, - ], - { - title: `Delete Template`, - action: () => { - deleteTemplate({ - sandboxId: template.sandbox.id, - templateId: template.id, - }).then(() => refetch()); - return true; - }, - color: theme.red.darken(0.2)(), - }, - ]} - key={template.id} - > - history.push(sandboxUrl(template.sandbox))} - /> - - ))} - - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/OwnedTemplates/index.ts b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/OwnedTemplates/index.ts deleted file mode 100644 index 72d275a0ab3..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/OwnedTemplates/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { OwnedTemplates } from './OwnedTemplates'; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/Templates.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/Templates.tsx deleted file mode 100644 index 5f39fa04b01..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/Templates.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -import { Helmet } from 'react-helmet'; -import { RouteComponentProps } from 'react-router'; -import { Container } from './elements'; -import { BookmarkedTemplates } from './BookmarkedTemplates'; -import { OwnedTemplates } from './OwnedTemplates'; - -type TemplatesProps = RouteComponentProps<{ teamId: string }> & {}; - -export const Templates = (props: TemplatesProps) => { - const { teamId } = props.match.params; - - return ( - - - {teamId ? 'Team' : 'My'} Templates - CodeSandbox - - - - - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/elements.ts b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/elements.ts deleted file mode 100644 index 0e307d40a57..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/elements.ts +++ /dev/null @@ -1,29 +0,0 @@ -import styled from 'styled-components'; - -export const Container = styled.div` - width: 100%; - height: 100%; - box-sizing: border-box; - padding-left: 2rem; -`; - -export const Grid = styled.section` - padding-top: 2rem; - display: grid; - grid-gap: 32px; - grid-template-columns: repeat(auto-fill, 203.5px); - - height: auto; - overflow-y: auto; - - margin-bottom: 2rem; -`; - -export const EmptyTitle = styled.h2` - font-size: 16px; - line-height: 1.6; - margin: 18px 0; - width: 500px; - - color: rgba(255, 255, 255, 0.7); -`; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/index.ts b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/index.ts deleted file mode 100644 index 189ee6db947..00000000000 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Templates } from './Templates'; diff --git a/packages/app/src/app/pages/NewDashboard/Content/routes/Templates/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/routes/Templates/index.tsx rename to packages/app/src/app/pages/Dashboard/Content/routes/Templates/index.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Content/utils.ts b/packages/app/src/app/pages/Dashboard/Content/utils.ts similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Content/utils.ts rename to packages/app/src/app/pages/Dashboard/Content/utils.ts diff --git a/packages/app/src/app/pages/NewDashboard/Header/index.tsx b/packages/app/src/app/pages/Dashboard/Header/index.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Header/index.tsx rename to packages/app/src/app/pages/Dashboard/Header/index.tsx diff --git a/packages/app/src/app/pages/Dashboard/Navigation/Actions/ExploreAction.tsx b/packages/app/src/app/pages/Dashboard/Navigation/Actions/ExploreAction.tsx deleted file mode 100644 index 8b3ac23f4ca..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/Actions/ExploreAction.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import Tooltip from '@codesandbox/common/lib/components/Tooltip'; -import { exploreUrl } from '@codesandbox/common/lib/utils/url-generator'; -import React, { FunctionComponent } from 'react'; -import FlameIcon from 'react-icons/lib/go/flame'; - -import { Action } from '../elements'; - -export const ExploreAction: FunctionComponent = () => ( - - - - - - - -); diff --git a/packages/app/src/app/pages/Dashboard/Navigation/Actions/NewSandboxAction.tsx b/packages/app/src/app/pages/Dashboard/Navigation/Actions/NewSandboxAction.tsx deleted file mode 100644 index e0f1e9c2efd..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/Actions/NewSandboxAction.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import Tooltip from '@codesandbox/common/lib/components/Tooltip'; -import React, { FunctionComponent } from 'react'; -import PlusIcon from 'react-icons/lib/go/plus'; - -import { useOvermind } from 'app/overmind'; - -import { Action } from '../elements'; - -export const NewSandboxAction: FunctionComponent = () => { - const { - actions: { openCreateSandboxModal }, - } = useOvermind(); - - return ( - openCreateSandboxModal({})} - style={{ fontSize: '1.125rem' }} - > - - - - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Navigation/Actions/PatronAction.tsx b/packages/app/src/app/pages/Dashboard/Navigation/Actions/PatronAction.tsx deleted file mode 100644 index c5cd4f8102b..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/Actions/PatronAction.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import Tooltip from '@codesandbox/common/lib/components/Tooltip'; -import { patronUrl } from '@codesandbox/common/lib/utils/url-generator'; -import React, { FunctionComponent } from 'react'; -import { Link } from 'react-router-dom'; - -// @ts-ignore -import PatronBadge from '-!svg-react-loader!@codesandbox/common/lib/utils/badges/svg/patron-4.svg'; - -import { Action } from '../elements'; - -export const PatronAction: FunctionComponent = () => ( - - - - - - - -); diff --git a/packages/app/src/app/pages/Dashboard/Navigation/Actions/SearchAction.tsx b/packages/app/src/app/pages/Dashboard/Navigation/Actions/SearchAction.tsx deleted file mode 100644 index 6c1b901a3a2..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/Actions/SearchAction.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import Tooltip from '@codesandbox/common/lib/components/Tooltip'; -import { searchUrl } from '@codesandbox/common/lib/utils/url-generator'; -import React, { FunctionComponent } from 'react'; -import SearchIcon from 'react-icons/lib/go/search'; -import Media from 'react-media'; -import { Link } from 'react-router-dom'; - -import { HeaderSearchBar } from 'app/components/HeaderSearchBar'; - -import { Action } from '../elements'; - -type Props = { - searchNoInput?: boolean; -}; -export const SearchAction: FunctionComponent = ({ searchNoInput }) => ( - - - {matches => - matches || searchNoInput ? ( - - - - - - ) : ( - - ) - } - - -); diff --git a/packages/app/src/app/pages/Dashboard/Navigation/Actions/ShowNotificationsAction.tsx b/packages/app/src/app/pages/Dashboard/Navigation/Actions/ShowNotificationsAction.tsx deleted file mode 100644 index e8c9c7ac03f..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/Actions/ShowNotificationsAction.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import Tooltip from '@codesandbox/common/lib/components/Tooltip'; -import React, { FunctionComponent } from 'react'; -import BellIcon from 'react-icons/lib/md/notifications'; - -import { useOvermind } from 'app/overmind'; - -import { Action, UnreadIcon } from '../elements'; - -type Props = { - openNotifications: ( - event: React.MouseEvent - ) => void; -}; -export const ShowNotificationsAction: FunctionComponent = ({ - openNotifications, -}) => { - const { - state: { - userNotifications: { unreadCount }, - }, - } = useOvermind(); - - return ( - 0 ? 'Show Notifications' : 'No Notifications'} - as="button" - onClick={openNotifications} - style={{ fontSize: '1.25rem', position: 'relative' }} - > - 0 ? 'Show Notifications' : 'No Notifications'} - placement="bottom" - > - - - {unreadCount > 0 && } - - - ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Navigation/Actions/index.ts b/packages/app/src/app/pages/Dashboard/Navigation/Actions/index.ts deleted file mode 100644 index 1ba686c0dfb..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/Actions/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { ExploreAction } from './ExploreAction'; -export { NewSandboxAction } from './NewSandboxAction'; -export { PatronAction } from './PatronAction'; -export { SearchAction } from './SearchAction'; -export { ShowNotificationsAction } from './ShowNotificationsAction'; diff --git a/packages/app/src/app/pages/Dashboard/Navigation/Notifications/elements.ts b/packages/app/src/app/pages/Dashboard/Navigation/Notifications/elements.ts deleted file mode 100644 index 16dd048b7fe..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/Notifications/elements.ts +++ /dev/null @@ -1,91 +0,0 @@ -import styled, { css } from 'styled-components'; -import delayEffect from '@codesandbox/common/lib/utils/animation/delay-effect'; - -export const Container = styled.div` - overflow: hidden; - box-sizing: border-box; - text-align: left; - line-height: 1.6; - z-index: 10; - color: rgba(255, 255, 255, 0.8); - font-size: 0.875rem; - font-weight: 600; - - border-radius: 2px; - box-shadow: 0 3px 3px rgba(0, 0, 0, 0.3); - - background-color: ${props => props.theme.background}; -`; - -export const NotificationsContainer = styled.div` - color: rgba(255, 255, 255, 0.6); - max-height: 500px; - overflow-y: auto; -`; - -export const NoNotifications = styled.div` - padding: 0.75rem 1rem; -`; - -export const Loading = styled.div` - ${delayEffect(1)}; - - padding: 0.75rem 1rem; -`; - -export const Title = styled.div` - color: white; - padding: 0.75rem 1rem; - - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); -`; - -export const NotificationContainer = styled.div<{ - read?: boolean; - success?: boolean; -}>` - transition: 0.3s ease all; - padding: 0.75rem 1rem; - - border-left: 2px solid transparent; - - border-bottom: 1px solid rgba(0, 0, 0, 0.2); - - ${props => - props.read - ? css` - border-left-color: transparent; - - &:hover { - background-color: ${props.theme.background2}; - } - ` - : css` - border-left-color: ${props.theme.secondary.clearer(0.3)()}; - - &:hover { - border-left-color: ${props.theme.secondary()}; - background-color: ${props.theme.background2}; - } - `}; - - ${props => - props.success && - css` - border-left-color: ${props.theme.green.clearer(0.2)()}; - - &:hover { - border-left-color: ${props.theme.green()}; - } - `}; -`; - -export const NotificationImage = styled.img` - border-radius: 4px; - width: 24px; - height: 24px; - min-width: 24px; - min-height: 24px; - margin-right: 1rem; - margin-top: 0.25rem; -`; diff --git a/packages/app/src/app/pages/Dashboard/Navigation/Notifications/index.tsx b/packages/app/src/app/pages/Dashboard/Navigation/Notifications/index.tsx deleted file mode 100644 index a6ee0706a22..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/Notifications/index.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import gql from 'graphql-tag'; -import React from 'react'; -import { Query } from 'react-apollo'; - -import { - Container, - Loading, - NoNotifications, - NotificationsContainer, - Title, -} from './elements'; -import { SandboxInvitation } from './notifications/SandboxInvitation'; -import { TeamAccepted } from './notifications/TeamAccepted'; -import { TeamInvite } from './notifications/TeamInvite'; - -export const VIEW_QUERY = gql` - query RecentNotifications { - me { - notifications( - limit: 20 - orderBy: { field: "insertedAt", direction: ASC } - ) { - id - type - data - read - } - } - } -`; - -const getNotificationComponent = (type, data, read) => { - const parsedData = JSON.parse(data); - - if (type === 'team_invite') { - return ( - - ); - } - if (type === 'team_accepted') { - return ( - - ); - } - if (type === 'sandbox_invitation') { - return ( - - ); - } - - return
; -}; - -export const Notifications = props => ( - - Notifications - - - {({ loading, error, data }: any) => { - if (error) { - return ( - - Something went wrong while fetching notifications - - ); - } - - if (loading) { - return Loading Notifications...; - } - - if (data.me.notifications.length === 0) { - return ( - - You don{"'"}t have any notifications - - ); - } - - return ( -
- {data.me.notifications.map(notification => ( -
- {getNotificationComponent( - notification.type, - notification.data, - notification.read - )} -
- ))} -
- ); - }} -
-
-
-); diff --git a/packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/SandboxInvitation.tsx b/packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/SandboxInvitation.tsx deleted file mode 100644 index 3ed620987e2..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/SandboxInvitation.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; - -import { sandboxUrl } from '@codesandbox/common/lib/utils/url-generator'; -import { Authorization } from 'app/graphql/types'; -import { NotificationImage as Image } from '../elements'; -import { Container, W } from './elements'; - -interface ISandboxInvitationProps { - read: boolean; - inviterAvatar: string; - inviterName: string; - sandboxId: string; - sandboxAlias: string | null; - sandboxTitle: string | null; - authorization: Authorization; -} - -export const SandboxInvitation = ({ - read, - inviterAvatar, - inviterName, - sandboxId, - sandboxAlias, - sandboxTitle, - authorization, -}: ISandboxInvitationProps) => { - const niceSandboxTitle = sandboxTitle || sandboxAlias || sandboxId; - let nicePermissionName = 'view'; - if (authorization === Authorization.Comment) { - nicePermissionName = 'comment on'; - } else if (authorization === Authorization.WriteCode) { - nicePermissionName = 'edit'; - } - - return ( -
- - -
- {inviterName} invited you to {nicePermissionName}{' '} - {niceSandboxTitle} -
-
-
- ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/TeamAccepted.tsx b/packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/TeamAccepted.tsx deleted file mode 100644 index 4fae63e089a..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/TeamAccepted.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; - -import { NotificationImage as Image } from '../elements'; -import { Container, W } from './elements'; - -interface Props { - read: boolean; - teamName: string; - userName: string; - userAvatar: string; -} - -export const TeamAccepted = ({ - read, - teamName, - userName, - userAvatar, -}: Props) => ( -
- - -
- {userName} accepted your invitation to join {teamName}! -
-
-
-); diff --git a/packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/TeamInvite.tsx b/packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/TeamInvite.tsx deleted file mode 100644 index cb4d390da68..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/TeamInvite.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { teamOverviewUrl } from '@codesandbox/common/lib/utils/url-generator'; -import React, { FunctionComponent } from 'react'; -import { Mutation } from 'react-apollo'; - -import { useOvermind } from 'app/overmind'; -import { - REJECT_TEAM_INVITATION, - ACCEPT_TEAM_INVITATION, -} from 'app/pages/Dashboard/queries'; -import history from 'app/utils/history'; - -import { NotificationImage as Image } from '../elements'; - -import { Container, Buttons, Button, W } from './elements'; - -type Props = { - read: boolean; - teamId: string; - teamName: string; - inviterName: string; - inviterAvatar: string; -}; -export const TeamInvite: FunctionComponent = ({ - read, - teamId, - teamName, - inviterName, - inviterAvatar, -}) => { - const { - actions: { acceptTeamInvitation, rejectTeamInvitation }, - } = useOvermind(); - - return ( -
- - - -
- {inviterName} invites you to join team {teamName} -
-
- - {!read && ( - - rejectTeamInvitation({ teamName })} - > - {(mutate, { loading }) => ( - - )} - - - { - acceptTeamInvitation({ teamName, teamId }); - - history.push(teamOverviewUrl(teamId)); - }} - > - {(mutate, { loading }) => ( - - )} - - - )} -
- ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/elements.ts b/packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/elements.ts deleted file mode 100644 index d3b593cba84..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/Notifications/notifications/elements.ts +++ /dev/null @@ -1,50 +0,0 @@ -import styled, { css } from 'styled-components'; -import { NotificationContainer } from '../elements'; - -export const Container = styled(NotificationContainer)` - display: flex; - text-decoration: none; - color: rgba(255, 255, 255, 0.6); -`; - -export const Buttons = styled.div` - display: flex; -`; - -export const Button = styled.div<{ decline?: boolean; disabled?: boolean }>` - transition: 0.3s ease background-color; - height: 36px; - width: 100%; - - color: white; - background-color: ${props => - props.decline ? props.theme.red : props.theme.secondary}; - - border: 2px solid - ${props => - props.decline - ? props.theme.red.lighten(0.1) - : props.theme.secondary.lighten(0.2)}; - display: flex; - align-items: center; - justify-content: center; - - cursor: pointer; - - ${props => - props.disabled && - css` - pointer-events: none; - opacity: 0.5; - `}; - &:hover { - background-color: ${props => - props.decline - ? props.theme.red.lighten(0.1) - : props.theme.secondary.lighten(0.2)}; - } -`; - -export const W = styled.span` - color: rgba(255, 255, 255, 0.95); -`; diff --git a/packages/app/src/app/pages/Dashboard/Navigation/elements.ts b/packages/app/src/app/pages/Dashboard/Navigation/elements.ts deleted file mode 100644 index 9735e5a64cb..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/elements.ts +++ /dev/null @@ -1,95 +0,0 @@ -import styled, { css } from 'styled-components'; -import Logo from '@codesandbox/common/lib/components/Logo'; -import RowBase from '@codesandbox/common/lib/components/flex/Row'; - -export const LogoWithBorder = styled(Logo)` - padding-right: 1rem; - color: white; -`; - -export const Border = styled.hr` - display: inline-block; - height: 22px; - width: 1px; - border: none; - border-right: 1px solid rgba(255, 255, 255, 0.4); -`; - -export const Title = styled.h1` - margin-left: 1rem; - font-size: 1.125rem; - color: white; - font-weight: 300; -`; - -export const Actions = styled.div` - display: flex; - justify-content: center; - align-items: center; - margin: 0 1rem; -`; - -export const Action = styled.div<{ noHover?: boolean }>` - ${({ noHover }) => css` - display: flex; - justify-content: center; - align-items: center; - transition: 0.3s ease all; - margin: 0 1rem; - cursor: pointer; - color: white; - opacity: 0.8; - background: transparent; - border: none; - padding: 0; - - ${noHover - ? css` - color: rgba(255, 255, 255, 0.8); - opacity: 1; - ` - : css` - &:hover { - opacity: 1; - } - `}; - `}; -`; - -export const UnreadIcon = styled.div` - ${({ theme }) => css` - position: absolute; - width: 8px; - height: 8px; - border-radius: 50%; - background-color: ${theme.secondary}; - - top: 4px; - right: 0; - `}; -`; - -export const Row = styled(RowBase)<{ float?: boolean }>` - ${({ float }) => - float && - css` - position: absolute; - left: 0; - top: 0; - right: 0; - padding: 1rem; - `}; -`; - -export const TitleWrapper = styled(RowBase)` - position: relative; - z-index: 10; -`; - -export const Wrapper = styled(RowBase)` - position: relative; - z-index: 10; - @media (max-width: 768px) { - display: none; - } -`; diff --git a/packages/app/src/app/pages/Dashboard/Navigation/index.tsx b/packages/app/src/app/pages/Dashboard/Navigation/index.tsx deleted file mode 100644 index 913e0825ce9..00000000000 --- a/packages/app/src/app/pages/Dashboard/Navigation/index.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { Overlay } from 'app/components/Overlay'; -import { useOvermind } from 'app/overmind'; -import React, { FunctionComponent } from 'react'; - -import { SignInButton } from 'app/pages/common/SignInButton'; -import { UserMenu } from 'app/pages/common/UserMenu'; -import { - ExploreAction, - NewSandboxAction, - SearchAction, - ShowNotificationsAction, -} from './Actions'; -import { - Actions, - Border, - LogoWithBorder, - Row, - Title, - TitleWrapper, - Wrapper, -} from './elements'; -import { Notifications } from './Notifications'; - -type Props = { - float?: boolean; - searchNoInput?: boolean; - title: string; -}; -export const Navigation: FunctionComponent = ({ - float = false, - searchNoInput, - title, -}) => { - const { - actions: { - userNotifications: { notificationsClosed, notificationsOpenedOld }, - }, - state: { - isLoggedIn, - isAuthenticating, - user, - userNotifications: { notificationsOpened: notificationsMenuOpened }, - }, - } = useOvermind(); - - return ( - - - - - - - - - {title} - - - {isAuthenticating ? null : ( - - - - - - - {user && ( - - {open => } - - )} - - - - - {isLoggedIn ? : } - - )} - - ); -}; diff --git a/packages/app/src/app/pages/NewDashboard/Sidebar/ContextMenu.tsx b/packages/app/src/app/pages/Dashboard/Sidebar/ContextMenu.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Sidebar/ContextMenu.tsx rename to packages/app/src/app/pages/Dashboard/Sidebar/ContextMenu.tsx diff --git a/packages/app/src/app/pages/Dashboard/Sidebar/Item/elements.js b/packages/app/src/app/pages/Dashboard/Sidebar/Item/elements.js deleted file mode 100644 index c6e71e811eb..00000000000 --- a/packages/app/src/app/pages/Dashboard/Sidebar/Item/elements.js +++ /dev/null @@ -1,52 +0,0 @@ -import styled, { css } from 'styled-components'; -import { NavLink } from 'react-router-dom'; -import ChevronRight from 'react-icons/lib/md/chevron-right'; - -export const AnimatedChevron = styled(ChevronRight)` - transition: 0.25s ease transform; - transform: rotate(${props => (props.open ? 90 : 0)}deg); - margin-right: 0.25rem; - width: 1rem; -`; - -export const Container = styled(NavLink)` - transition: 0.3s ease all; - display: flex; - width: 100%; - height: 2.5rem; - user-select: none; - - align-items: center; - - padding: 0 0.5rem; - box-sizing: border-box; - - color: ${props => props.theme.placeholder}; - text-decoration: none; - background-color: transparent; - - cursor: pointer; - position: relative; - - &:hover { - color: white; - } - - ${props => - props.active && - css` - background-color: ${props.theme.secondary}; - color: white; - `}; -`; - -export const IconContainer = styled.div` - display: flex; - align-items: center; - width: 2rem; - font-size: 1.25rem; -`; - -export const ItemName = styled.div` - font-size: 0.875rem; -`; diff --git a/packages/app/src/app/pages/Dashboard/Sidebar/Item/index.js b/packages/app/src/app/pages/Dashboard/Sidebar/Item/index.js deleted file mode 100644 index 0bb20171f5a..00000000000 --- a/packages/app/src/app/pages/Dashboard/Sidebar/Item/index.js +++ /dev/null @@ -1,116 +0,0 @@ -import React from 'react'; -import { Route } from 'react-router-dom'; -import { Animate } from 'react-show'; -import { ContextMenu } from 'app/components/ContextMenu'; -import { - AnimatedChevron, - Container, - IconContainer, - ItemName, -} from './elements'; - -const getContainer = contextItems => { - if (contextItems) { - return props => ( - - {React.createElement(Container, props)} - - ); - } - - return Container; -}; - -export class Item extends React.Component { - state = { - open: this.props.openByDefault, - }; - - toggleOpen = e => { - e.preventDefault(); - this.setState(state => ({ open: !state.open })); - }; - - UNSAFE_componentWillReceiveProps(nextProps) { - if (nextProps.openByDefault === true && !this.props.openByDefault) { - this.setState({ open: true }); - } - } - - render() { - const { - name, - contextItems, - Icon, - path, - children, - style, - active, - noActive, - ...props - } = this.props; - - const UsedContainer = getContainer(contextItems); - - return ( - - {res => { - const isActive = - (!noActive && res.match && res.match.isExact) || active; - const isOpen = - this.state.open === undefined ? isActive : this.state.open; - - if ( - (res.match || isActive) && - this.state.open === undefined && - children - ) { - this.setState({ open: true }); - } - return ( - <> - - {children ? ( - - ) : ( -
- )} - - - - {name} - - - {children && ( - - {children} - - )} - - ); - }} - - ); - } -} diff --git a/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/FolderEntry/CreateFolderEntry.tsx b/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/FolderEntry/CreateFolderEntry.tsx deleted file mode 100644 index cf9d6b84380..00000000000 --- a/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/FolderEntry/CreateFolderEntry.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import React from 'react'; -import { Mutation } from 'react-apollo'; - -import AddFolderIcon from 'react-icons/lib/md/create-new-folder'; -import Input from '@codesandbox/common/lib/components/Input'; -import track from '@codesandbox/common/lib/utils/analytics'; -import { ESC } from '@codesandbox/common/lib/utils/keycodes'; - -import { - CreateDirectoryContainer, - IconContainer, - AnimatedChevron, -} from './elements'; - -import { - PATHED_SANDBOXES_FOLDER_QUERY, - CREATE_FOLDER_MUTATION, -} from '../../../queries'; - -interface Props { - basePath: string; - teamId: string | undefined; - close: () => void; - depth: number; - noFocus?: boolean; -} - -export const CreateFolderEntry = ({ - basePath, - teamId, - noFocus, - close, - depth, -}: Props) => { - let input; - return ( - - {mutate => ( -
{ - e.preventDefault(); - const path = basePath + '/' + input.value; - - track('Dashboard - Create Directory', { - path, - }); - - mutate({ - variables: { path, teamId }, - optimisticResponse: { - __typename: 'Mutation', - createCollection: { - id: 'optimistic-id', - path, - __typename: 'Collection', - }, - }, - update: (proxy, { data: { createCollection } }) => { - const variables: { teamId?: string } = {}; - if (teamId) { - variables.teamId = teamId; - } - // Read the data from our cache for this query. - const d: { me: any } = proxy.readQuery({ - query: PATHED_SANDBOXES_FOLDER_QUERY, - variables, - }); - - // Add our collection from the mutation to the end. - d.me.collections.push(createCollection); - // Write our data back to the cache. - proxy.writeQuery({ - query: PATHED_SANDBOXES_FOLDER_QUERY, - variables, - data: d, - }); - }, - }); - - input.value = ''; - - close(); - }} - > - - - - - {' '} - { - if (e.keyCode === ESC) { - e.preventDefault(); - close(); - } - }} - ref={el => { - if (el) { - if (!noFocus) { - el.focus(); - el.select(); - } - input = el; - } - }} - block - /> - -
- )} -
- ); -}; diff --git a/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/FolderEntry/elements.ts b/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/FolderEntry/elements.ts deleted file mode 100644 index 14b6125e086..00000000000 --- a/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/FolderEntry/elements.ts +++ /dev/null @@ -1,47 +0,0 @@ -import styled from 'styled-components'; -import { NavLink } from 'react-router-dom'; -import ChevronRight from 'react-icons/lib/md/chevron-right'; - -export const Container = styled(NavLink)<{ - depth?: number; -}>` - transition: 0.25s ease all; - display: flex; - align-items: center; - height: 2rem; - - color: rgba(255, 255, 255, 0.6); - text-decoration: none; - - border-left: 2px solid transparent; - padding-left: ${props => 1 + (props.depth || 0) * 0.75}rem; - - user-select: none; - - cursor: pointer; - - &:hover { - color: rgba(255, 255, 255, 0.8); - } - - &:focus { - outline: none; - border-color: ${props => props.theme.secondary.clearer(0.5)}; - color: rgba(255, 255, 255, 0.8); - } -`; - -export const CreateDirectoryContainer = Container.withComponent('div'); - -export const IconContainer = styled.div` - display: flex; - align-items: center; - width: 3rem; - font-size: 1.125rem; -`; - -export const AnimatedChevron = styled(ChevronRight)<{ open?: boolean }>` - transition: 0.25s ease transform; - transform: rotate(${props => (props.open ? 90 : 0)}deg); - margin-right: 0.25rem; -`; diff --git a/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/FolderEntry/index.tsx b/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/FolderEntry/index.tsx deleted file mode 100644 index 15cf385f56c..00000000000 --- a/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/FolderEntry/index.tsx +++ /dev/null @@ -1,434 +0,0 @@ -import React from 'react'; - -import FolderIcon from 'react-icons/lib/md/folder'; -import AddFolderIcon from 'react-icons/lib/md/create-new-folder'; -import RenameIcon from 'react-icons/lib/md/mode-edit'; -import TrashIcon from 'react-icons/lib/md/delete'; -import { Mutation } from 'react-apollo'; -import { DropTarget, DragSource } from 'react-dnd'; -import track from '@codesandbox/common/lib/utils/analytics'; -import { withRouter } from 'react-router-dom'; -import { History } from 'history'; -import { client } from 'app/graphql/client'; - -import { Animate as ReactShow } from 'react-show'; -import { join, dirname } from 'path'; - -import theme from '@codesandbox/common/lib/theme'; - -import { ContextMenu } from 'app/components/ContextMenu'; - -import Input from '@codesandbox/common/lib/components/Input'; -import { - ARROW_LEFT, - ARROW_RIGHT, - ESC, -} from '@codesandbox/common/lib/utils/keycodes'; - -import { - PathedSandboxesFoldersQuery, - PathedSandboxesFoldersQueryVariables, -} from 'app/graphql/types'; -import { Container, AnimatedChevron, IconContainer } from './elements'; - -import getDirectChildren from '../../../utils/get-direct-children'; -import { entryTarget, collectTarget } from '../folder-drop-target'; - -import { CreateFolderEntry } from './CreateFolderEntry'; - -import { - PATHED_SANDBOXES_FOLDER_QUERY, - PATHED_SANDBOXES_CONTENT_QUERY, - DELETE_FOLDER_MUTATION, - RENAME_FOLDER_MUTATION, -} from '../../../queries'; - -type Props = { - name: string; - path: string; - url: string; - folders: { path: string }[]; - foldersByPath: { [path: string]: string }; - selectedSandboxes: string[]; - depth: number; - toToggle?: boolean; - allowCreate?: boolean; - open?: boolean; - basePath: string; - teamId: string; - onSelect: (params: { teamId: string; path: string }) => void; - currentPath: string; - currentTeamId: string; - - // dnd handlers - canDrop?: boolean; - isOver?: boolean; - isDragging?: boolean; - connectDropTarget?: any; - connectDragSource?: any; - - history?: History; -}; - -type State = { - open: boolean; - creatingDirectory: boolean; - renamingDirectory: boolean; -}; - -// eslint-disable-next-line import/no-mutable-exports -let DropFolderEntry: React.ComponentClass = null; -class FolderEntry extends React.Component { - state = { - open: this.props.open, - creatingDirectory: false, - renamingDirectory: false, - }; - - static defaultProps = { - depth: 0, - }; - - UNSAFE_componentWillReceiveProps(nextProps) { - if ( - (this.state.open == null || this.state.open === false) && - nextProps.open === true - ) { - this.setState({ open: true }); - } - } - - toggleOpen = e => { - e.preventDefault(); - e.stopPropagation(); - this.setState(state => ({ open: !state.open })); - }; - - handleBlur = () => { - this.setState({ renamingDirectory: false, open: true }); - }; - - handleSelect = () => { - this.props.onSelect({ - teamId: this.props.teamId, - path: this.props.path, - }); - }; - - handleKeyDown = e => { - if (!this.state.renamingDirectory) { - if (e.keyCode === ARROW_RIGHT) { - this.setState({ open: true }); - } else if (e.keyCode === ARROW_LEFT) { - this.setState({ open: false }); - } - } - }; - - render() { - const { - name, - path, - url, - folders, - selectedSandboxes, - foldersByPath, - depth, - isOver, - toToggle = true, - allowCreate = true, - canDrop, - connectDropTarget, - connectDragSource, - isDragging, - basePath, - teamId, - onSelect, - currentPath, - currentTeamId, - history, - } = this.props; - - const children = getDirectChildren(path, folders); - - const menuItems = [ - { - title: 'Rename Folder', - icon: RenameIcon, - action: () => { - this.setState({ renamingDirectory: true }); - return true; - }, - }, - { - title: 'Delete Folder', - icon: TrashIcon, - color: theme.red.darken(0.2)(), - action: () => { - track('Dashboard - Folder Deleted'); - client.mutate({ - mutation: DELETE_FOLDER_MUTATION, - variables: { path, teamId }, - - refetchQueries: [ - { - query: PATHED_SANDBOXES_CONTENT_QUERY, - variables: { path: '/', teamId }, - }, - ], - update: (cache, { data: { deleteCollection } }) => { - const variables: PathedSandboxesFoldersQueryVariables = { - teamId, - }; - - const cacheData = cache.readQuery< - PathedSandboxesFoldersQuery, - PathedSandboxesFoldersQueryVariables - >({ - query: PATHED_SANDBOXES_FOLDER_QUERY, - variables, - }); - - cache.writeQuery({ - query: PATHED_SANDBOXES_FOLDER_QUERY, - variables, - data: { - ...cacheData, - me: { - // @ts-ignore - ...cacheData.me, - collections: deleteCollection, - }, - }, - }); - }, - }); - - const subPath = path - .split('/') - .slice(0, -1) - .join('/'); - - history.replace(`${basePath}${subPath}`); - - return true; - }, - }, - ]; - - if (allowCreate) { - menuItems.unshift({ - title: 'Create Folder', - icon: AddFolderIcon, - action: () => { - this.setState({ creatingDirectory: true, open: true }); - return true; - }, - }); - } - - // TODO: fix the typings of this container and make sure it works with `as` - const UnTypedContainer = Container as any; - - return connectDropTarget( - connectDragSource( -
- - - - {toToggle ? ( - 0 ? 1 : 0 }} - /> - ) : null} - - {' '} - {this.state.renamingDirectory ? ( - - {(mutate, { loading }) => { - let input; - - const submit = e => { - track('Dashboard - Folder Renamed'); - if (e) { - e.preventDefault(); - } - mutate({ - variables: { - path, - newPath: join(dirname(path), input.value), - teamId, - newTeamId: teamId, - }, - update: (cache, { data: { renameCollection } }) => { - const variables: { teamId?: string } = {}; - if (teamId) { - variables.teamId = teamId; - } - - const cacheData: { me: any } = cache.readQuery({ - query: PATHED_SANDBOXES_FOLDER_QUERY, - variables, - }); - - cache.writeQuery({ - query: PATHED_SANDBOXES_FOLDER_QUERY, - data: { - ...cacheData, - me: { - ...cacheData.me, - collections: renameCollection, - }, - }, - variables, - }); - const modifiedPath = path - .split('/') - .slice(0, -1) - .join('/'); - - history.replace( - `${basePath}${modifiedPath}/${input.value}` - ); - }, - }); - - this.handleBlur(); - }; - - return loading ? ( - input.value - ) : ( -
- { - if (node) { - input = node; - node.focus(); - node.select(); - } - }} - defaultValue={name} - onBlur={this.handleBlur} - onKeyDown={e => { - if (e.keyCode === ESC) { - this.handleBlur(); - } - }} - /> -
- ); - }} -
- ) : ( - name - )} -
-
- - 0 && !isDragging && this.state.open && toToggle - } - duration={250} - stayMounted={false} - style={{ - height: 'auto', - overflow: 'hidden', - }} - transitionOnMount - start={{ - height: 0, // The starting style for the component. - // If the 'leave' prop isn't defined, 'start' is reused! - }} - > - {Array.from(children) - .sort() - .map((childName: string) => { - const childPath = join(path, childName); - const childUrl = join(url, encodeURIComponent(childName)); - - return ( - - ); - })} - - {this.state.creatingDirectory && ( - this.setState({ creatingDirectory: false })} - basePath={path} - /> - )} -
- ) - ); - } -} - -const entrySource = { - canDrag: () => true, - - beginDrag: props => { - if (props.closeTree) props.closeTree(); - return { - path: props.path, - teamId: props.teamId, - }; - }, -}; -const collectSource = (connect, monitor) => ({ - connectDragSource: connect.dragSource(), - isDragging: monitor.isDragging(), -}); - -DropFolderEntry = (withRouter( - // @ts-ignore Don't know how to mix dnd and react-router with right typings - DropTarget( - ['SANDBOX', 'FOLDER'], - entryTarget, - collectTarget - )(DragSource('FOLDER', entrySource, collectSource)(FolderEntry)) -) as unknown) as React.ComponentClass; - -export { DropFolderEntry }; diff --git a/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/elements.js b/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/elements.js deleted file mode 100644 index 93758a5c873..00000000000 --- a/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/elements.js +++ /dev/null @@ -1,8 +0,0 @@ -import styled from 'styled-components'; - -export const Container = styled.div` - margin: 0.25rem 0; - color: rgba(255, 255, 255, 0.6); - font-weight: 600; - font-size: 0.875rem; -`; diff --git a/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/folder-drop-target.js b/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/folder-drop-target.js deleted file mode 100644 index de456864112..00000000000 --- a/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/folder-drop-target.js +++ /dev/null @@ -1,162 +0,0 @@ -import { basename, join } from 'path'; - -import { client } from 'app/graphql/client'; - -import { - ADD_SANDBOXES_TO_FOLDER_MUTATION, - PATHED_SANDBOXES_CONTENT_QUERY, - RENAME_FOLDER_MUTATION, -} from '../../queries'; - -function addSandboxesToCollection(props, item) { - const { path, teamId, selectedSandboxes } = props; - - client.mutate({ - mutation: ADD_SANDBOXES_TO_FOLDER_MUTATION, - variables: { - collectionPath: path || '/', - teamId, - sandboxIds: selectedSandboxes, - }, - optimisticResponse: { - __typename: 'Mutation', - addToCollection: { - __typename: 'Collection', - // We keep this empty, because it will be loaded later regardless. We - // just want the main directory to update immediately - sandboxes: [], - }, - }, - - refetchQueries: ['DeletedSandboxes'], - - update: (cache, { data: { addToCollection } }) => { - // Update new folder - try { - const usedPath = path || '/'; - const variables = { path: usedPath }; - - if (teamId) { - variables.teamId = teamId; - } - - const cacheData = cache.readQuery({ - query: PATHED_SANDBOXES_CONTENT_QUERY, - variables, - }); - - cacheData.me.collection.sandboxes = addToCollection.sandboxes; - - cache.writeQuery({ - query: PATHED_SANDBOXES_CONTENT_QUERY, - variables, - data: cacheData, - }); - } catch (e) { - // Means that the cache didn't exist yet, no biggie - } - - if (!item.removedAt) { - // Update old folders - const { collectionPath } = item; - - const variables = { path: collectionPath }; - - if (item.collectionTeamId) { - variables.teamId = item.collectionTeamId; - } - - const oldFolderCacheData = cache.readQuery({ - query: PATHED_SANDBOXES_CONTENT_QUERY, - variables, - }); - - oldFolderCacheData.me.collection.sandboxes = oldFolderCacheData.me.collection.sandboxes.filter( - x => !selectedSandboxes.includes(x.id) - ); - - cache.writeQuery({ - query: PATHED_SANDBOXES_CONTENT_QUERY, - variables, - data: oldFolderCacheData, - }); - } - }, - }); -} - -function addFolderToFolder(props, item) { - const newPath = join(props.path || '/', basename(item.path)); - client.mutate({ - mutation: RENAME_FOLDER_MUTATION, - refetchQueries: ['PathedSandboxesFolders'], - variables: { - path: item.path, - newPath, - teamId: item.teamId, - newTeamId: props.teamId, - }, - }); -} - -export const entryTarget = { - drop: (props, monitor) => { - if (monitor == null) return; - - // Check if only child is selected: - if (!monitor.isOver({ shallow: true })) return; - - const type = monitor.getItemType(); - const item = monitor.getItem(); - - if (item && type) { - switch (type) { - case 'SANDBOX': { - addSandboxesToCollection(props, item); - break; - } - case 'FOLDER': { - addFolderToFolder(props, item); - break; - } - - default: - break; - } - } - }, - - canDrop: (props, monitor) => { - if (monitor == null) return false; - const source = monitor.getItem(); - if (source == null) return false; - - const type = monitor.getItemType(); - - if (type === 'SANDBOX') { - if ( - !source.removedAt && - source.collectionPath === (props.path || '/') && - // Double check because we may compare null to undefined - // eslint-disable-next-line eqeqeq - source.collectionTeamId == props.teamId - ) { - return false; - } - return true; - } - return source.path !== props.path; - }, -}; - -export function collectTarget(connectMonitor, monitor) { - return { - // Call this function inside render() - // to let React DnD handle the drag events: - connectDropTarget: connectMonitor.dropTarget(), - // You can ask the monitor about the current drag state: - isOver: monitor.isOver({ shallow: true }), - canDrop: monitor.canDrop(), - itemType: monitor.getItemType(), - }; -} diff --git a/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/index.js b/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/index.js deleted file mode 100644 index 22f16feac9b..00000000000 --- a/packages/app/src/app/pages/Dashboard/Sidebar/SandboxesItem/index.js +++ /dev/null @@ -1,149 +0,0 @@ -import React from 'react'; -import { withRouter } from 'react-router-dom'; -import { DropTarget } from 'react-dnd'; -import AddFolderIcon from 'react-icons/lib/md/create-new-folder'; -import { Query } from 'react-apollo'; -import { DelayedAnimation } from 'app/components/DelayedAnimation'; -import InfoIcon from '-!svg-react-loader!@codesandbox/common/lib/icons/sandbox.svg'; -import { Item } from '../Item'; -import { Container } from './elements'; -import { DropFolderEntry } from './FolderEntry'; -import { CreateFolderEntry } from './FolderEntry/CreateFolderEntry'; - -import { entryTarget, collectTarget } from './folder-drop-target'; - -import getChildCollections from '../../utils/get-child-collections'; - -import { PATHED_SANDBOXES_FOLDER_QUERY } from '../../queries'; - -class SandboxesItemComponent extends React.Component { - state = { - creatingDirectory: false, - }; - - handleSelect = () => { - this.props.onSelect({ - path: '/', - teamId: this.props.teamId, - }); - }; - - render() { - const { - isOver, - canDrop, - teamId, - teamName, - connectDropTarget, - openByDefault, - onSelect, - currentPath, - currentTeamId, - selectedSandboxes, - } = this.props; - - const basePath = teamId - ? `/dashboard/teams/${teamId}/sandboxes` - : '/dashboard/sandboxes'; - - return connectDropTarget( -
- { - this.setState({ creatingDirectory: true }); - return true; - }, - }, - ]} - > - - {({ data, loading, error }) => { - if (loading) { - return ( - - Loading... - - ); - } - - if (error || !data.me) { - return
Error!
; - } - const { children, folders, foldersByPath } = getChildCollections( - data.me.collections - ); - - return ( - - {Array.from(children) - .sort() - .map(name => { - const path = '/' + name; - const url = basePath + '/' + encodeURIComponent(name); - return ( - - ); - })} - {(this.state.creatingDirectory || children.size === 0) && ( - { - this.setState({ creatingDirectory: false }); - }} - /> - )} - - ); - }} -
-
-
- ); - } -} - -export const SandboxesItem = DropTarget( - ['SANDBOX', 'FOLDER'], - entryTarget, - collectTarget -)(withRouter(SandboxesItemComponent)); diff --git a/packages/app/src/app/pages/Dashboard/Sidebar/TemplateItem/index.tsx b/packages/app/src/app/pages/Dashboard/Sidebar/TemplateItem/index.tsx deleted file mode 100644 index 56a24f32dff..00000000000 --- a/packages/app/src/app/pages/Dashboard/Sidebar/TemplateItem/index.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import React from 'react'; -import { DropTarget } from 'react-dnd'; -import { withRouter, RouteComponentProps } from 'react-router-dom'; -// @ts-ignore -import TemplateIcon from '-!svg-react-loader!@codesandbox/common/lib/icons/template.svg'; -import { Item } from '../Item'; -import { MAKE_TEMPLATE_DROP_KEY } from '../../Content/SandboxCard'; - -interface ITemplateItemProps { - currentPath: string; - teamId?: string; - canDrop?: boolean; - isOver?: boolean; - connectDropTarget?: any; -} - -const TemplateItemComponent: React.FC = ({ - currentPath, - isOver, - canDrop, - connectDropTarget, - teamId, -}) => { - const url = teamId - ? `/dashboard/teams/${teamId}/templates` - : `/dashboard/templates`; - - return connectDropTarget( -
- -
- ); -}; - -export const entryTarget = { - drop: (props, monitor) => { - if (monitor == null) return {}; - - // Check if only child is selected: - if (!monitor.isOver({ shallow: true })) return {}; - - // Used in SandboxCard - return { [MAKE_TEMPLATE_DROP_KEY]: true, teamId: props.teamId }; - }, - - canDrop: (props, monitor) => { - if (monitor == null) return false; - const source = monitor.getItem(); - if (source == null) return false; - - return !props.removedAt; - }, -}; - -export function collectTarget(connectMonitor, monitor) { - return { - // Call this function inside render() - // to let React DnD handle the drag events: - connectDropTarget: connectMonitor.dropTarget(), - // You can ask the monitor about the current drag state: - isOver: monitor.isOver({ shallow: true }), - canDrop: monitor.canDrop(), - itemType: monitor.getItemType(), - }; -} - -export const TemplateItem = DropTarget( - ['SANDBOX'], - entryTarget, - collectTarget -)(withRouter(TemplateItemComponent)); diff --git a/packages/app/src/app/pages/Dashboard/Sidebar/TrashItem/index.tsx b/packages/app/src/app/pages/Dashboard/Sidebar/TrashItem/index.tsx deleted file mode 100644 index df4b054b534..00000000000 --- a/packages/app/src/app/pages/Dashboard/Sidebar/TrashItem/index.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from 'react'; -import { DropTarget } from 'react-dnd'; -import TrashIcon from 'react-icons/lib/md/delete'; - -import { withRouter, RouteComponentProps } from 'react-router-dom'; - -import { Item } from '../Item'; -import { DELETE_SANDBOX_DROP_KEY } from '../../Content/SandboxCard'; - -interface Props { - currentPath: string; - isOver: boolean; - canDrop: boolean; - connectDropTarget: (target: React.ReactElement) => React.ReactElement; -} - -const TrashItemComponent: React.FC = ({ - currentPath, - isOver, - canDrop, - connectDropTarget, -}) => - connectDropTarget( -
- -
- ); - -export const entryTarget = { - drop: (_, monitor) => { - if (monitor == null) return {}; - - // Check if only child is selected: - if (!monitor.isOver({ shallow: true })) return {}; - - // Used in SandboxCard - return { [DELETE_SANDBOX_DROP_KEY]: true }; - }, - - canDrop: (props, monitor) => { - if (monitor == null) return false; - const source = monitor.getItem(); - if (source == null) return false; - - return !props.removedAt; - }, -}; - -export function collectTarget(connectMonitor, monitor) { - return { - // Call this function inside render() - // to let React DnD handle the drag events: - connectDropTarget: connectMonitor.dropTarget(), - // You can ask the monitor about the current drag state: - isOver: monitor.isOver({ shallow: true }), - canDrop: monitor.canDrop(), - itemType: monitor.getItemType(), - }; -} - -export const TrashItem = DropTarget( - ['SANDBOX'], - entryTarget, - collectTarget -)(withRouter(TrashItemComponent)); diff --git a/packages/app/src/app/pages/NewDashboard/Sidebar/WorkspaceSwitcher.tsx b/packages/app/src/app/pages/Dashboard/Sidebar/WorkspaceSwitcher.tsx similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Sidebar/WorkspaceSwitcher.tsx rename to packages/app/src/app/pages/Dashboard/Sidebar/WorkspaceSwitcher.tsx diff --git a/packages/app/src/app/pages/NewDashboard/Sidebar/constants.ts b/packages/app/src/app/pages/Dashboard/Sidebar/constants.ts similarity index 100% rename from packages/app/src/app/pages/NewDashboard/Sidebar/constants.ts rename to packages/app/src/app/pages/Dashboard/Sidebar/constants.ts diff --git a/packages/app/src/app/pages/Dashboard/Sidebar/elements.ts b/packages/app/src/app/pages/Dashboard/Sidebar/elements.ts deleted file mode 100644 index 80b826fd9ca..00000000000 --- a/packages/app/src/app/pages/Dashboard/Sidebar/elements.ts +++ /dev/null @@ -1,30 +0,0 @@ -import styled from 'styled-components'; - -export const Items = styled.div` - margin-top: 0.5rem; - width: 100%; -`; - -export const CategoryHeader = styled.div` - display: block; - transition: 0.3s ease color; - - margin-bottom: 0.75rem; - margin-left: 1rem; - padding-top: 1rem; - text-transform: uppercase; - font-size: 0.875rem; - color: rgba(255, 255, 255, 0.5); - text-decoration: none; - font-weight: 600; -`; - -export const SidebarStyled = styled.aside` - width: 275px; - overflow-y: auto; -`; - -export const InputWrapper = styled.div` - margin: 0 1rem; - margin-bottom: 1.5rem; -`; diff --git a/packages/app/src/app/pages/Dashboard/Sidebar/index.tsx b/packages/app/src/app/pages/Dashboard/Sidebar/index.tsx index 490cf928f88..533ce445c98 100644 --- a/packages/app/src/app/pages/Dashboard/Sidebar/index.tsx +++ b/packages/app/src/app/pages/Dashboard/Sidebar/index.tsx @@ -1,128 +1,673 @@ -import { Button } from '@codesandbox/common/lib/components/Button'; -import Input from '@codesandbox/common/lib/components/Input'; -import { teamOverviewUrl } from '@codesandbox/common/lib/utils/url-generator'; +import React, { useState } from 'react'; +import { Link as RouterLink, useLocation, useHistory } from 'react-router-dom'; +import { orderBy } from 'lodash-es'; +import { join, dirname } from 'path'; import { useOvermind } from 'app/overmind'; -import history from 'app/utils/history'; -import React from 'react'; -import { Query } from 'react-apollo'; -import PeopleIcon from 'react-icons/lib/md/people'; -import { Route, withRouter } from 'react-router-dom'; -import DashboardIcon from '-!svg-react-loader!@codesandbox/common/lib/icons/dashboard.svg'; - -import { TEAMS_QUERY } from '../queries'; -import { CategoryHeader, InputWrapper, Items, SidebarStyled } from './elements'; -import { Item } from './Item'; -import { SandboxesItem } from './SandboxesItem'; -import { TemplateItem } from './TemplateItem'; -import { TrashItem } from './TrashItem'; - -const SidebarComponent = () => { +import { motion, AnimatePresence } from 'framer-motion'; +import { dashboard as dashboardUrls } from '@codesandbox/common/lib/utils/url-generator'; +import { ESC, ENTER } from '@codesandbox/common/lib/utils/keycodes'; +import track from '@codesandbox/common/lib/utils/analytics'; +import { + Element, + List, + ListAction, + ListItem, + Link, + Text, + Menu, + Stack, + Icon, + IconButton, + Button, + Input, + IconNames, +} from '@codesandbox/components'; +import css from '@styled-system/css'; +import merge from 'deepmerge'; +import { ContextMenu } from './ContextMenu'; +import { DashboardBaseFolder, PageTypes } from '../types'; +import { Position } from '../Components/Selection'; +import { SIDEBAR_WIDTH } from './constants'; +import { WorkspaceSwitcher } from './WorkspaceSwitcher'; +import { DragItemType, useDrop } from '../utils/dnd'; + +const SidebarContext = React.createContext(null); + +interface SidebarProps { + visible: boolean; + onSidebarToggle: () => void; + css?: any; + style?: React.CSSProperties; + id?: string; +} + +export const Sidebar: React.FC = ({ + visible, + onSidebarToggle, + ...props +}) => { + const { state, actions } = useOvermind(); + const [activeAccount, setActiveAccount] = useState<{ + username: string | null; + avatarUrl: string | null; + }>({ + username: null, + avatarUrl: null, + }); + const { dashboard, user, activeTeam } = state; + + React.useEffect(() => { + actions.dashboard.getAllFolders(); + }, [actions.dashboard, state.activeTeam]); + + React.useEffect(() => { + if (state.activeTeam) { + const team = dashboard.teams.find(({ id }) => id === state.activeTeam); + + if (team) + setActiveAccount({ username: team.name, avatarUrl: team.avatarUrl }); + } else if (user) { + setActiveAccount({ + username: user.username, + avatarUrl: user.avatarUrl, + }); + } + }, [state.activeTeam, state.activeTeamInfo, dashboard.teams, user]); + + const inTeamContext = + activeAccount && user && activeAccount.username !== user.username; + + const folders = dashboard.allCollections || []; + + // context menu for folders + const [menuVisible, setMenuVisibility] = React.useState(true); + const [menuPosition, setMenuPosition] = React.useState({ + x: null, + y: null, + }); + const [ + menuFolder, + setMenuFolder, + ] = React.useState(null); + const [isRenamingFolder, setRenamingFolder] = React.useState(false); + const [newFolderPath, setNewFolderPath] = React.useState(null); + + const menuState = { + menuFolder, + setMenuFolder, + setMenuVisibility, + menuPosition, + setMenuPosition, + isRenamingFolder, + setRenamingFolder, + newFolderPath, + setNewFolderPath, + }; + + return ( + + + + + + + + + + + + + + + + + + + + + {visible && ( + + )} + + + + ); +}; + +// I hate this! but we need this until I refactor how +// components are structured — Sid +// https://linear.app/issue/CSB-118 +const linkStyles = { + width: '100%', + height: '100%', + display: 'flex', + alignItems: 'center', + paddingLeft: 8, + paddingRight: 8, + flexShrink: 0, +}; + +const canNotAcceptSandboxes: PageTypes[] = ['home', 'recents']; +const canNotAcceptFolders: PageTypes[] = [ + 'home', + 'recents', + 'drafts', + 'templates', +]; + +const isSamePath = ( + draggedItem: DragItemType, + currentPage: PageTypes, + dropPath: string +) => { + if (!draggedItem) return false; + + if ( + draggedItem.type === 'sandbox' && + draggedItem.sandbox.collection?.path === dropPath + ) { + return true; + } + + if (draggedItem.type === 'template' && currentPage === 'templates') { + return true; + } + + if ( + draggedItem.type === 'folder' && + (draggedItem.path === dropPath || draggedItem.parent === dropPath) + ) { + return true; + } + + return false; +}; + +interface RowItemProps { + name: string; + path: string; + icon: IconNames; + page: PageTypes; + setFoldersVisibility?: (val: boolean) => void; + folderPath?: string; + style?: React.CSSProperties; +} + +const RowItem: React.FC = ({ + name, + path, + folderPath = path, + page, + icon, + setFoldersVisibility = null, + ...props +}) => { + const accepts: Array<'sandbox' | 'folder' | 'template'> = []; + if (!canNotAcceptSandboxes.includes(page)) { + accepts.push('template'); + accepts.push('sandbox'); + } + if (!canNotAcceptFolders.includes(page)) accepts.push('folder'); + + const usedPath = folderPath || path; + const [{ canDrop, isOver, isDragging }, dropRef] = useDrop({ + accept: accepts, + drop: item => ({ + page, + path: usedPath, + isSamePath: isSamePath(item, page, usedPath), + }), + collect: monitor => ({ + isOver: monitor.isOver(), + canDrop: + monitor.canDrop() && !isSamePath(monitor.getItem(), page, usedPath), + isDragging: !!monitor.getItem(), + }), + }); + + const { onSidebarToggle } = React.useContext(SidebarContext); + + const linkTo: string = path; + + const location = useLocation(); + const isCurrentLink = linkTo.replace(/\?.*/, '') === location.pathname; + const history = useHistory(); + + /** Toggle nested folders when user + * is drags an item over a folder after a treshold + * We open All Sandboxes instantly because that's the root + * and you can't drop anything in it + */ + const HOVER_THRESHOLD = name === 'All Sandboxes' ? 0 : 500; // ms + const isOverCache = React.useRef(false); + + React.useEffect(() => { + if (!isOver) isOverCache.current = false; + else isOverCache.current = true; + + const handler = () => { + if (isOverCache.current && setFoldersVisibility) { + setFoldersVisibility(true); + } + }; + + const timer = window.setTimeout(handler, HOVER_THRESHOLD); + return () => window.clearTimeout(timer); + }, [isOver, setFoldersVisibility, HOVER_THRESHOLD]); + + return ( + theme.speeds[4], + a: { + ':focus': { + // focus state is handled by ListAction:focus-within + outline: 'none', + }, + }, + }, + props.style || {} + ) + )} + > + {props.children || ( + { + if (event.keyCode === ENTER) { + history.push(linkTo, { focus: 'FIRST_ITEM' }); + } + }} + > + + + + {name} + + )} + + ); +}; + +interface NestableRowItemProps { + name: string; + folderPath: string; + path: string; + folders: DashboardBaseFolder[]; +} + +const NestableRowItem: React.FC = ({ + name, + path, + folderPath, + folders, +}) => { + const { actions, state } = useOvermind(); + const { - state: { dashboard: dashboardState }, - actions: { dashboard: dashboardAction }, - } = useOvermind(); + menuState: { + menuFolder, + setMenuFolder, + setMenuVisibility, + setMenuPosition, + isRenamingFolder, + setRenamingFolder, + newFolderPath, + setNewFolderPath, + }, + } = React.useContext(SidebarContext); + + const [foldersVisible, setFoldersVisibility] = React.useState(false); + + let hasNewNestedFolder = false; + if (newFolderPath !== null) { + const newFolderParent = newFolderPath.replace('/__NEW__', ''); + if (name === 'All Sandboxes') { + hasNewNestedFolder = true; + } else if (newFolderParent.length && folderPath.includes(newFolderParent)) { + hasNewNestedFolder = true; + } + } + + const location = useLocation(); + const currentFolderLocationPath = dashboardUrls.allSandboxes(folderPath); + React.useEffect(() => { + // Auto open folder in the sidebar if it's opened + const pathName = location.pathname; + const prefixCheck = + folderPath === '/' + ? currentFolderLocationPath + : currentFolderLocationPath + '/'; + + if (pathName.startsWith(prefixCheck) && !foldersVisible) { + setFoldersVisibility(true); + } + + // We don't want to recalculate after mount + // eslint-disable-next-line + }, [location.pathname, currentFolderLocationPath, setFoldersVisibility]); + + React.useEffect(() => { + if (hasNewNestedFolder) setFoldersVisibility(true); + }, [hasNewNestedFolder]); + + const onContextMenu = event => { + event.preventDefault(); + setMenuVisibility(true); + setMenuFolder({ name, path: folderPath }); + setMenuPosition({ x: event.clientX, y: event.clientY }); + }; - const handleSearchFocus = () => { - history.push('/dashboard/search', { from: 'sandboxSearchFocused' }); + let subFolders: DashboardBaseFolder[]; + if (name === 'All Sandboxes') { + subFolders = folders.filter(folder => { + if (folder.path === newFolderPath) { + return newFolderPath.replace('/__NEW__', '') === ''; + } + return !folder.parent; + }); + } else { + subFolders = folders.filter(folder => { + const parentPath = folder.path + .split('/') + .slice(0, -1) + .join('/'); + + return parentPath === folderPath; + }); + } + + const nestingLevel = + folderPath === '/' ? 0 : folderPath.split('/').length - 1; + const history = useHistory(); + + /* Rename logic */ + const isRenaming = isRenamingFolder && menuFolder.path === folderPath; + const isNewFolder = newFolderPath === folderPath; + const [newName, setNewName] = React.useState(name); + + const onChange = (event: React.ChangeEvent) => { + setNewName(event.target.value); + }; + const onInputKeyDown = (event: React.KeyboardEvent) => { + if (event.keyCode === ESC) { + // Reset value and exit without saving + setNewName(name); + setRenamingFolder(false); + setNewFolderPath(null); + } }; - const handleSearchChange: React.ChangeEventHandler = e => { - dashboardAction.searchChanged({ search: e.target.value }); + const onSubmit = async (event?: React.FormEvent) => { + if (event) event.preventDefault(); + + if (name === newName) { + // nothing to do here + } else if (isNewFolder) { + if (newName) { + const sanitizedPath = folderPath.replace('__NEW__', newName); + await actions.dashboard.createFolder(sanitizedPath); + track('Dashboard - Create Directory', { + source: 'Sidebar', + dashboardVersion: 2, + folderPath: sanitizedPath, + }); + } + } else { + const newPath = join(dirname(folderPath), newName); + await actions.dashboard.renameFolder({ + path: folderPath, + newPath, + teamId: state.activeTeam, + newTeamId: state.activeTeam, + }); + + track('Dashboard - Rename Folder', { + source: 'Sidebar', + dashboardVersion: 2, + }); + + if (currentFolderLocationPath === location.pathname) { + // if this directory is opened + history.push(dashboardUrls.allSandboxes(newPath, state.activeTeam)); + } + } + + setNewFolderPath(null); + return setRenamingFolder(false); }; + const onInputBlur = () => { + // save value when you click outside or tab away + setRenamingFolder(false); + setNewFolderPath(null); + onSubmit(); + }; + + const folderUrl = dashboardUrls.allSandboxes(folderPath, state.activeTeam); + return ( - - - - - - + - {({ location, match }) => { - const testRegex = /\/dashboard.*?sandboxes/; - - const path = location.pathname.replace(testRegex, ''); - const currentTeamId = match ? match.params.teamId : undefined; - - return ( - <> - - + history.push(folderUrl)} + onContextMenu={onContextMenu} + onKeyDown={event => { + if (event.keyCode === ENTER && !isRenaming && !isNewFolder) { + history.push(folderUrl, { + focus: 'FIRST_ITEM', + }); + } + }} + tabIndex={0} + style={{ + ...linkStyles, + paddingLeft: nestingLevel * 16, + }} + > + {subFolders.length ? ( + { + setFoldersVisibility(!foldersVisible); + event.stopPropagation(); + }} + css={css({ + width: 5, + height: '100%', + borderRadius: 0, + svg: { + transform: foldersVisible ? 'rotate(0deg)' : 'rotate(-90deg)', + transition: 'transform ease-in-out', + transitionDuration: theme => theme.speeds[2], + }, + })} + /> + ) : ( + + )} - + + + + {isRenaming || isNewFolder ? ( +
+ +
+ ) : ( + + {name} + + )} + + +
- - - - - - - {({ loading, data, error }: any) => { - if (loading || error || !data.me || !(data && data.me)) { - return null; - } - - const { teams = [] } = data.me; - - return teams.map(({ id, name }) => ( -
- - {name} - - - - - - -
- )); - }} -
- - ); - }} -
- -
- -
-
+ + {foldersVisible && ( + + {orderBy(subFolders, 'name') + .sort(a => 1) + .map(folder => ( + + ))} + + )} + + ); }; -export const Sidebar = withRouter(SidebarComponent); diff --git a/packages/app/src/app/pages/Dashboard/elements.ts b/packages/app/src/app/pages/Dashboard/elements.ts deleted file mode 100644 index bcb69a882f4..00000000000 --- a/packages/app/src/app/pages/Dashboard/elements.ts +++ /dev/null @@ -1,67 +0,0 @@ -import RightIconBase from 'react-icons/lib/md/keyboard-arrow-right'; -import LeftIconBase from 'react-icons/lib/md/keyboard-arrow-left'; -import styled, { css } from 'styled-components'; - -export const Container = styled.div` - height: 100%; - width: 100%; - - color: rgba(255, 255, 255, 0.8); -`; - -export const LeftIcon = styled(LeftIconBase)` - color: #ffffff; -`; - -export const RightIcon = styled(RightIconBase)` - color: #ffffff; -`; - -export const ShowSidebarButton = styled.button` - display: none; - transition: opacity 200ms ease; - border: none; - background-color: rgba(255, 255, 255, 0.1); - - @media (max-width: 768px) { - display: block; - } -`; - -const paddingTop = css` - padding-top: 100px; -`; - -export const SidebarContainer = styled.div<{ active: boolean }>` - display: flex; - box-sizing: border-box; - - height: 100vh; - background-color: ${props => props.theme.background}; - - ${paddingTop}; - - box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3); - - @media (max-width: 768px) { - width: 0; - position: fixed; - transition: width 200ms ease; - z-index: 1; - - ${props => - props.active && - css` - width: 275px; - `}; - } -`; - -export const ContentContainer = styled.div` - ${paddingTop}; - - box-sizing: border-box; - height: 100vh; - overflow-y: auto; - width: 100%; -`; diff --git a/packages/app/src/app/pages/Dashboard/index.tsx b/packages/app/src/app/pages/Dashboard/index.tsx index bb61e7d719b..80c38e98f81 100644 --- a/packages/app/src/app/pages/Dashboard/index.tsx +++ b/packages/app/src/app/pages/Dashboard/index.tsx @@ -1,75 +1,128 @@ import { signInPageUrl } from '@codesandbox/common/lib/utils/url-generator'; -import React, { useState, useEffect, FunctionComponent } from 'react'; -import { withRouter, Redirect, RouteComponentProps } from 'react-router-dom'; - -import { client } from 'app/graphql/client'; +import React, { FunctionComponent, useEffect } from 'react'; +import { Redirect, useLocation } from 'react-router-dom'; +import { DndProvider } from 'react-dnd'; +import Media from 'react-media'; +import Backend from 'react-dnd-html5-backend'; import { useOvermind } from 'app/overmind'; -import { ThemeProvider } from '@codesandbox/components'; -import { Navigation } from './Navigation'; - -import Content from './Content'; import { - Container, - ContentContainer, - LeftIcon, - RightIcon, - SidebarContainer, - ShowSidebarButton, -} from './elements'; + ThemeProvider, + Stack, + Element, + SkipNav, +} from '@codesandbox/components'; +import { createGlobalStyle, useTheme } from 'styled-components'; +import css from '@styled-system/css'; + +import { Header } from './Header'; import { Sidebar } from './Sidebar'; +import { SIDEBAR_WIDTH } from './Sidebar/constants'; +import { Content } from './Content'; -type Props = RouteComponentProps; -const DashboardComponent: FunctionComponent = ({ history }) => { +const GlobalStyles = createGlobalStyle({ + body: { overflow: 'hidden' }, +}); + +export const Dashboard: FunctionComponent = () => { const { - actions: { - dashboard: { dashboardMounted }, - }, state: { hasLogIn }, + actions, } = useOvermind(); - const [showSidebar, setShowSidebar] = useState(false); - - useEffect(() => { - dashboardMounted(); - // Reset store so new visits get fresh data - return () => client.resetStore(); - }, [dashboardMounted]); + // only used for mobile + const [sidebarVisible, setSidebarVisibility] = React.useState(false); + const onSidebarToggle = React.useCallback( + () => setSidebarVisibility(s => !s), + [setSidebarVisibility] + ); + const theme = useTheme() as any; + const location = useLocation(); useEffect(() => { - history.listen(({ state }) => { - if (state?.from === 'sandboxSearchFocused') { - return; - } - - setShowSidebar(false); - }); - }, [history]); + const searchParams = new URLSearchParams(location.search); + if (searchParams.get('workspace')) { + actions.setActiveTeam({ id: searchParams.get('workspace') }); + } + }, [location.search, actions]); if (!hasLogIn) { - return ; + return ; } return ( - - - -
- - + + + + +
+ + + {match => + match ? ( + + ) : ( + + { + /* do nothing */ + }} + style={{ + // We set sidebar as absolute so that content can + // take 100% width, this helps us enable dragging + // sandboxes onto the sidebar more freely. + position: 'absolute', + height: 'calc(100% - 48px)', + }} + /> + + ) + } + - setShowSidebar(show => !show)}> - {showSidebar ? : } - - - - - - -
-
+ + + + + +
); }; - -export const Dashboard = withRouter(DashboardComponent); diff --git a/packages/app/src/app/pages/Dashboard/queries.ts b/packages/app/src/app/pages/Dashboard/queries.ts index c6eb191f407..f5c799c018f 100644 --- a/packages/app/src/app/pages/Dashboard/queries.ts +++ b/packages/app/src/app/pages/Dashboard/queries.ts @@ -1,511 +1,276 @@ -import { client } from 'app/graphql/client'; -import { - AddToCollectionMutation, - AddToCollectionMutationVariables, - DeleteSandboxesMutation, - DeleteSandboxesMutationVariables, - DeletedSandboxesQuery, - DeletedSandboxesQueryVariables, - PathedSandboxesQuery, - PathedSandboxesQueryVariables, - PermanentlyDeleteSandboxesMutation, - PermanentlyDeleteSandboxesMutationVariables, -} from 'app/graphql/types'; -import gql from 'graphql-tag'; -import immer from 'immer'; - -const SIDEBAR_COLLECTION_FRAGMENT = gql` - fragment SidebarCollection on Collection { - id - path - } -`; - -export const SANDBOX_FRAGMENT = gql` - fragment Sandbox on Sandbox { - id - alias - title - description - insertedAt - updatedAt - removedAt - privacy - screenshotUrl - screenshotOutdated - - source { - template - } - - customTemplate { - id - } - - forkedTemplate { - id - color - } - - teamId - - collection { - path - teamId - } - } -`; - -const TEAM_FRAGMENT = gql` - fragment Team on Team { - id - name - inviteToken - description - creatorId - - users { - id - name - username - avatarUrl - } - - invitees { - id - name - username - avatarUrl - } - } -`; - -export const TEAMS_QUERY = gql` - query TeamsSidebar { - me { - teams { - id - name - } - } - } -`; - -export const CREATE_TEAM_MUTATION = gql` - mutation CreateTeam($name: String!) { - createTeam(name: $name) { - ...Team - } - } - ${TEAM_FRAGMENT} -`; - -export const PATHED_SANDBOXES_FOLDER_QUERY = gql` - query PathedSandboxesFolders($teamId: ID) { - me { - collections(teamId: $teamId) { - ...SidebarCollection - } - } - } - ${SIDEBAR_COLLECTION_FRAGMENT} -`; - -export const CREATE_FOLDER_MUTATION = gql` - mutation createCollection($path: String!, $teamId: ID) { - createCollection(path: $path, teamId: $teamId) { - ...SidebarCollection - } - } - ${SIDEBAR_COLLECTION_FRAGMENT} -`; - -export const DELETE_FOLDER_MUTATION = gql` - mutation deleteCollection($path: String!, $teamId: ID) { - deleteCollection(path: $path, teamId: $teamId) { - ...SidebarCollection - } - } - ${SIDEBAR_COLLECTION_FRAGMENT} -`; - -export const RENAME_FOLDER_MUTATION = gql` - mutation renameCollection( - $path: String! - $newPath: String! - $teamId: ID - $newTeamId: ID - ) { - renameCollection( - path: $path - newPath: $newPath - teamId: $teamId - newTeamId: $newTeamId - ) { - ...SidebarCollection - } - } - ${SIDEBAR_COLLECTION_FRAGMENT} -`; - -export const ADD_SANDBOXES_TO_FOLDER_MUTATION = gql` - mutation AddToCollection( - $collectionPath: String! - $sandboxIds: [ID!]! - $teamId: ID - ) { - addToCollection( - collectionPath: $collectionPath - sandboxIds: $sandboxIds - teamId: $teamId - ) { - sandboxes { - ...Sandbox - } - } - } - ${SANDBOX_FRAGMENT} -`; - -export const DELETE_SANDBOXES_MUTATION = gql` - mutation DeleteSandboxes($sandboxIds: [ID!]!) { - deleteSandboxes(sandboxIds: $sandboxIds) { - ...Sandbox - } - } - ${SANDBOX_FRAGMENT} -`; - -export const SET_SANDBOXES_PRIVACY_MUTATION = gql` - mutation SetSandboxesPrivacy($sandboxIds: [ID!]!, $privacy: Int!) { - setSandboxesPrivacy(sandboxIds: $sandboxIds, privacy: $privacy) { - ...Sandbox - } - } - ${SANDBOX_FRAGMENT} -`; - -export const RENAME_SANDBOX_MUTATION = gql` - mutation RenameSandbox($id: ID!, $title: String!) { - renameSandbox(id: $id, title: $title) { - ...Sandbox - } - } - ${SANDBOX_FRAGMENT} -`; - -export const PERMANENTLY_DELETE_SANDBOXES_MUTATION = gql` - mutation PermanentlyDeleteSandboxes($sandboxIds: [ID!]!) { - permanentlyDeleteSandboxes(sandboxIds: $sandboxIds) { - id - } - } -`; - -export const PATHED_SANDBOXES_CONTENT_QUERY = gql` - query PathedSandboxes($path: String!, $teamId: ID) { - me { - collections(teamId: $teamId) { - ...SidebarCollection - } - collection(path: $path, teamId: $teamId) { - id - path - sandboxes { - ...Sandbox - } - } - } - } - ${SANDBOX_FRAGMENT} - ${SIDEBAR_COLLECTION_FRAGMENT} -`; - -export const RECENT_SANDBOXES_CONTENT_QUERY = gql` - query RecentSandboxes($orderField: String!, $orderDirection: Direction!) { - me { - sandboxes( - limit: 20 - orderBy: { field: $orderField, direction: $orderDirection } - ) { - ...Sandbox - } - } - } - ${SANDBOX_FRAGMENT} -`; - -export const SEARCH_SANDBOXES_QUERY = gql` - query SearchSandboxes { - me { - sandboxes(orderBy: { field: "updated_at", direction: DESC }) { - ...Sandbox - } - } - } - ${SANDBOX_FRAGMENT} -`; - -export const DELETED_SANDBOXES_CONTENT_QUERY = gql` - query DeletedSandboxes { - me { - sandboxes( - showDeleted: true - orderBy: { field: "updated_at", direction: DESC } - ) { - ...Sandbox - } - } - } - ${SANDBOX_FRAGMENT} -`; - -export function addSandboxesToFolder( - selectedSandboxes: string[], - path: string, - teamId: string | null -) { - return client.mutate< - AddToCollectionMutation, - AddToCollectionMutationVariables - >({ - mutation: ADD_SANDBOXES_TO_FOLDER_MUTATION, - variables: { - sandboxIds: selectedSandboxes, - teamId, - collectionPath: path, - }, - optimisticResponse: { - __typename: 'RootMutationType', - addToCollection: { - __typename: 'Collection', - // We keep this empty, because it will be loaded later regardless. We - // just want the main directory to update immediately - sandboxes: [], - }, - }, - - refetchQueries: ['PathedSandboxes'], - }); -} - -export function undeleteSandboxes(selectedSandboxes) { - client.mutate({ - mutation: ADD_SANDBOXES_TO_FOLDER_MUTATION, - // @ts-ignore - variables: { - sandboxIds: selectedSandboxes.toJS - ? selectedSandboxes.toJS() - : selectedSandboxes, - collectionPath: '/', - }, - optimisticResponse: { - __typename: 'RootMutationType', - addToCollection: { - __typename: 'Collection', - // We keep this empty, because it will be loaded later regardless. We - // just want the main directory to update immediately - sandboxes: [], - }, - }, - - refetchQueries: ['DeletedSandboxes'], - }); -} - -export function permanentlyDeleteSandboxes(selectedSandboxes: string[]) { - return client.mutate< - PermanentlyDeleteSandboxesMutation, - PermanentlyDeleteSandboxesMutationVariables - >({ - mutation: PERMANENTLY_DELETE_SANDBOXES_MUTATION, - variables: { - sandboxIds: selectedSandboxes, - }, - update: cache => { - try { - const oldDeleteCache = cache.readQuery< - DeletedSandboxesQuery, - DeletedSandboxesQueryVariables - >({ - query: DELETED_SANDBOXES_CONTENT_QUERY, - }); - - const newDeleteCache = { - ...oldDeleteCache, - me: { - ...(oldDeleteCache && oldDeleteCache.me ? oldDeleteCache.me : null), - sandboxes: (oldDeleteCache?.me?.sandboxes || []).filter( - x => !selectedSandboxes.includes(x.id) - ), - }, - }; - - cache.writeQuery({ - query: DELETED_SANDBOXES_CONTENT_QUERY, - data: newDeleteCache, - }); - } catch (e) { - // cache doesn't exist, no biggie! - } - }, - }); -} - -export function deleteSandboxes(selectedSandboxes, collections = []) { - client.mutate({ - mutation: DELETE_SANDBOXES_MUTATION, - variables: { - sandboxIds: selectedSandboxes.toJS - ? selectedSandboxes.toJS() - : selectedSandboxes, - }, - refetchQueries: [ - 'DeletedSandboxes', - 'PathedSandboxes', - 'RecentSandboxes', - 'SearchSandboxes', - ], - update: cache => { - if (collections) { - collections.forEach(({ path, teamId }) => { - try { - const variables = { - path, - teamId, - }; - - const oldFolderCacheData = cache.readQuery< - PathedSandboxesQuery, - PathedSandboxesQueryVariables - >({ - query: PATHED_SANDBOXES_CONTENT_QUERY, - variables, - }); - - const data = immer(oldFolderCacheData, draft => { - if ( - !draft?.me?.collection || - !oldFolderCacheData?.me?.collection?.sandboxes - ) { - return; - } - draft.me.collection.sandboxes = oldFolderCacheData.me.collection.sandboxes.filter( - x => !selectedSandboxes.includes(x?.id) - ); - }); - - if (data) { - cache.writeQuery< - PathedSandboxesQuery, - PathedSandboxesQueryVariables - >({ - query: PATHED_SANDBOXES_CONTENT_QUERY, - variables, - data, - }); - } - } catch (e) { - // cache doesn't exist, no biggie! - } - }); - } - }, - }); -} - -export function setSandboxesPrivacy( - selectedSandboxes: string[], - privacy: 0 | 1 | 2 -) { - client.mutate({ - mutation: SET_SANDBOXES_PRIVACY_MUTATION, - variables: { - sandboxIds: selectedSandboxes, - privacy, - }, - }); -} - -export const TEAM_QUERY = gql` - query Team($id: ID!) { - me { - team(id: $id) { - ...Team - } - } - } - ${TEAM_FRAGMENT} -`; - -export const LEAVE_TEAM = gql` - mutation LeaveTeam($teamId: ID!) { - leaveTeam(teamId: $teamId) - } -`; - -export const REMOVE_FROM_TEAM = gql` - mutation RemoveFromTeam($teamId: ID!, $userId: ID!) { - removeFromTeam(teamId: $teamId, userId: $userId) { - ...Team - } - } - ${TEAM_FRAGMENT} -`; - -export const INVITE_TO_TEAM = gql` - mutation InviteToTeam($teamId: ID!, $username: String!) { - inviteToTeam(teamId: $teamId, username: $username) { - ...Team - } - } - ${TEAM_FRAGMENT} -`; - -export const INVITE_TO_TEAM_VIA_EMAIL = gql` - mutation InviteToTeamViaEmail($teamId: ID!, $email: String!) { - inviteToTeamViaEmail(teamId: $teamId, email: $email) - } -`; - -export const REVOKE_TEAM_INVITATION = gql` - mutation RevokeTeamInvitation($teamId: ID!, $userId: ID!) { - revokeTeamInvitation(teamId: $teamId, userId: $userId) { - ...Team - } - } - ${TEAM_FRAGMENT} -`; - -export const ACCEPT_TEAM_INVITATION = gql` - mutation AcceptTeamInvitation($teamId: ID!) { - acceptTeamInvitation(teamId: $teamId) { - ...Team - } - } - ${TEAM_FRAGMENT} -`; - -export const REJECT_TEAM_INVITATION = gql` - mutation RejectTeamInvitation($teamId: ID!) { - rejectTeamInvitation(teamId: $teamId) - } -`; - -export const SET_TEAM_DESCRIPTION = gql` - mutation SetTeamDescription($teamId: ID!, $description: String!) { - setTeamDescription(teamId: $teamId, description: $description) { - ...Team - } - } - ${TEAM_FRAGMENT} -`; - -export const SET_TEAM_NAME = gql` - mutation SetTeamName($teamId: ID!, $name: String!) { - setTeamName(teamId: $teamId, name: $name) { - ...Team - } - } - ${TEAM_FRAGMENT} -`; +// import { client } from 'app/graphql/client'; +// import { +// AddToCollectionMutation, +// AddToCollectionMutationVariables, +// DeleteSandboxesMutation, +// DeleteSandboxesMutationVariables, +// DeletedSandboxesQuery, +// DeletedSandboxesQueryVariables, +// PathedSandboxesQuery, +// PathedSandboxesQueryVariables, +// PermanentlyDeleteSandboxesMutation, +// PermanentlyDeleteSandboxesMutationVariables, +// } from 'app/graphql/types'; +// import gql from 'graphql-tag'; +// import immer from 'immer'; + +// export const PATHED_SANDBOXES_FOLDER_QUERY = gql` +// query PathedSandboxesFolders($teamId: ID) { +// me { +// collections(teamId: $teamId) { +// ...SidebarCollection +// } +// } +// } +// ${SIDEBAR_COLLECTION_FRAGMENT} +// `; + +// export const PATHED_SANDBOXES_CONTENT_QUERY = gql` +// query PathedSandboxes($path: String!, $teamId: ID) { +// me { +// collections(teamId: $teamId) { +// ...SidebarCollection +// } +// collection(path: $path, teamId: $teamId) { +// id +// path +// sandboxes { +// ...Sandbox +// } +// } +// } +// } +// ${SANDBOX_FRAGMENT} +// ${SIDEBAR_COLLECTION_FRAGMENT} +// `; + +// export const RECENT_SANDBOXES_CONTENT_QUERY = gql` +// query RecentSandboxes($orderField: String!, $orderDirection: Direction!) { +// me { +// sandboxes( +// limit: 7 +// orderBy: { field: $orderField, direction: $orderDirection } +// ) { +// ...Sandbox +// } +// } +// } +// ${SANDBOX_FRAGMENT} +// `; + +// export const RECENT_SANDBOXES_PAGE_QUERY = gql` +// query RecentSandboxes($orderField: String!, $orderDirection: Direction!) { +// me { +// sandboxes( +// limit: 50 +// orderBy: { field: $orderField, direction: $orderDirection } +// ) { +// ...Sandbox +// } +// } +// } +// ${SANDBOX_FRAGMENT} +// `; + +// export const SEARCH_SANDBOXES_QUERY = gql` +// query SearchSandboxes { +// me { +// sandboxes(orderBy: { field: "updated_at", direction: DESC }) { +// ...Sandbox +// } +// } +// } +// ${SANDBOX_FRAGMENT} +// `; + +// export const DELETED_SANDBOXES_CONTENT_QUERY = gql` +// query DeletedSandboxes { +// me { +// sandboxes( +// showDeleted: true +// orderBy: { field: "updated_at", direction: DESC } +// ) { +// ...Sandbox +// } +// } +// } +// ${SANDBOX_FRAGMENT} +// `; + +// export function addSandboxesToFolder( +// selectedSandboxes, +// path: string, +// teamId: string | null +// ) { +// return client.mutate< +// AddToCollectionMutation, +// AddToCollectionMutationVariables +// >({ +// mutation: ADD_SANDBOXES_TO_FOLDER_MUTATION, +// variables: { +// sandboxIds: selectedSandboxes, +// teamId, +// collectionPath: path, +// }, +// optimisticResponse: { +// __typename: 'RootMutationType', +// addToCollection: { +// __typename: 'Collection', +// // We keep this empty, because it will be loaded later regardless. We +// // just want the main directory to update immediately +// sandboxes: [], +// }, +// }, + +// refetchQueries: ['PathedSandboxes'], +// }); +// } + +// export function undeleteSandboxes(selectedSandboxes) { +// client.mutate({ +// mutation: ADD_SANDBOXES_TO_FOLDER_MUTATION, +// // @ts-ignore +// variables: { +// sandboxIds: selectedSandboxes.toJS +// ? selectedSandboxes.toJS() +// : selectedSandboxes, +// collectionPath: '/', +// }, +// optimisticResponse: { +// __typename: 'RootMutationType', +// addToCollection: { +// __typename: 'Collection', +// // We keep this empty, because it will be loaded later regardless. We +// // just want the main directory to update immediately +// sandboxes: [], +// }, +// }, + +// refetchQueries: ['DeletedSandboxes'], +// }); +// } + +// export function permanentlyDeleteSandboxes(selectedSandboxes: string[]) { +// return client.mutate< +// PermanentlyDeleteSandboxesMutation, +// PermanentlyDeleteSandboxesMutationVariables +// >({ +// mutation: PERMANENTLY_DELETE_SANDBOXES_MUTATION, +// variables: { +// sandboxIds: selectedSandboxes, +// }, +// update: cache => { +// try { +// const oldDeleteCache = cache.readQuery< +// DeletedSandboxesQuery, +// DeletedSandboxesQueryVariables +// >({ +// query: DELETED_SANDBOXES_CONTENT_QUERY, +// }); + +// const newDeleteCache = { +// ...oldDeleteCache, +// me: { +// ...(oldDeleteCache && oldDeleteCache.me ? oldDeleteCache.me : null), +// sandboxes: (oldDeleteCache?.me?.sandboxes || []).filter( +// x => !selectedSandboxes.includes(x.id) +// ), +// }, +// }; + +// cache.writeQuery({ +// query: DELETED_SANDBOXES_CONTENT_QUERY, +// data: newDeleteCache, +// }); +// } catch (e) { +// // cache doesn't exist, no biggie! +// } +// }, +// }); +// } + +// export function deleteSandboxes(selectedSandboxes, collections = []) { +// client.mutate({ +// mutation: DELETE_SANDBOXES_MUTATION, +// variables: { +// sandboxIds: selectedSandboxes.toJS +// ? selectedSandboxes.toJS() +// : selectedSandboxes, +// }, +// refetchQueries: [ +// 'DeletedSandboxes', +// 'PathedSandboxes', +// 'RecentSandboxes', +// 'SearchSandboxes', +// ], +// update: cache => { +// if (collections) { +// collections.forEach(({ path, teamId }) => { +// try { +// const variables = { +// path, +// teamId, +// }; + +// const oldFolderCacheData = cache.readQuery< +// PathedSandboxesQuery, +// PathedSandboxesQueryVariables +// >({ +// query: PATHED_SANDBOXES_CONTENT_QUERY, +// variables, +// }); + +// const data = immer(oldFolderCacheData, draft => { +// if ( +// !draft?.me?.collection || +// !oldFolderCacheData?.me?.collection?.sandboxes +// ) { +// return; +// } +// draft.me.collection.sandboxes = oldFolderCacheData.me.collection.sandboxes.filter( +// x => !selectedSandboxes.includes(x?.id) +// ); +// }); + +// if (data) { +// cache.writeQuery< +// PathedSandboxesQuery, +// PathedSandboxesQueryVariables +// >({ +// query: PATHED_SANDBOXES_CONTENT_QUERY, +// variables, +// data, +// }); +// } +// } catch (e) { +// // cache doesn't exist, no biggie! +// } +// }); +// } +// }, +// }); +// } + +// export function setSandboxesPrivacy( +// selectedSandboxes: string[], +// privacy: 0 | 1 | 2 +// ) { +// client.mutate({ +// mutation: SET_SANDBOXES_PRIVACY_MUTATION, +// variables: { +// sandboxIds: selectedSandboxes, +// privacy, +// }, +// }); +// } + +// export const TEAM_QUERY = gql` +// query Team($id: ID!) { +// me { +// team(id: $id) { +// ...Team +// } +// } +// } +// ${TEAM_FRAGMENT} +// `; diff --git a/packages/app/src/app/pages/NewDashboard/types.ts b/packages/app/src/app/pages/Dashboard/types.ts similarity index 100% rename from packages/app/src/app/pages/NewDashboard/types.ts rename to packages/app/src/app/pages/Dashboard/types.ts diff --git a/packages/app/src/app/pages/NewDashboard/utils/dnd.ts b/packages/app/src/app/pages/Dashboard/utils/dnd.ts similarity index 100% rename from packages/app/src/app/pages/NewDashboard/utils/dnd.ts rename to packages/app/src/app/pages/Dashboard/utils/dnd.ts diff --git a/packages/app/src/app/pages/Dashboard/utils/get-child-collections.js b/packages/app/src/app/pages/Dashboard/utils/get-child-collections.js index 46f7e895dec..c74b87578a4 100644 --- a/packages/app/src/app/pages/Dashboard/utils/get-child-collections.js +++ b/packages/app/src/app/pages/Dashboard/utils/get-child-collections.js @@ -1,11 +1,13 @@ import getDirectChildren from './get-direct-children'; export default function getChildCollections(folders, path = '/') { - const foldersByPath = {}; - - folders.forEach(collection => { - foldersByPath[collection?.path] = collection; - }); + const foldersByPath = folders.reduce( + (pathedFolders, folder) => ({ + ...pathedFolders, + [folder.path]: folder, + }), + {} + ); return { children: getDirectChildren(path, folders), diff --git a/packages/app/src/app/pages/NewDashboard/Sidebar/index.tsx b/packages/app/src/app/pages/NewDashboard/Sidebar/index.tsx deleted file mode 100644 index 533ce445c98..00000000000 --- a/packages/app/src/app/pages/NewDashboard/Sidebar/index.tsx +++ /dev/null @@ -1,673 +0,0 @@ -import React, { useState } from 'react'; -import { Link as RouterLink, useLocation, useHistory } from 'react-router-dom'; -import { orderBy } from 'lodash-es'; -import { join, dirname } from 'path'; -import { useOvermind } from 'app/overmind'; -import { motion, AnimatePresence } from 'framer-motion'; -import { dashboard as dashboardUrls } from '@codesandbox/common/lib/utils/url-generator'; -import { ESC, ENTER } from '@codesandbox/common/lib/utils/keycodes'; -import track from '@codesandbox/common/lib/utils/analytics'; -import { - Element, - List, - ListAction, - ListItem, - Link, - Text, - Menu, - Stack, - Icon, - IconButton, - Button, - Input, - IconNames, -} from '@codesandbox/components'; -import css from '@styled-system/css'; -import merge from 'deepmerge'; -import { ContextMenu } from './ContextMenu'; -import { DashboardBaseFolder, PageTypes } from '../types'; -import { Position } from '../Components/Selection'; -import { SIDEBAR_WIDTH } from './constants'; -import { WorkspaceSwitcher } from './WorkspaceSwitcher'; -import { DragItemType, useDrop } from '../utils/dnd'; - -const SidebarContext = React.createContext(null); - -interface SidebarProps { - visible: boolean; - onSidebarToggle: () => void; - css?: any; - style?: React.CSSProperties; - id?: string; -} - -export const Sidebar: React.FC = ({ - visible, - onSidebarToggle, - ...props -}) => { - const { state, actions } = useOvermind(); - const [activeAccount, setActiveAccount] = useState<{ - username: string | null; - avatarUrl: string | null; - }>({ - username: null, - avatarUrl: null, - }); - const { dashboard, user, activeTeam } = state; - - React.useEffect(() => { - actions.dashboard.getAllFolders(); - }, [actions.dashboard, state.activeTeam]); - - React.useEffect(() => { - if (state.activeTeam) { - const team = dashboard.teams.find(({ id }) => id === state.activeTeam); - - if (team) - setActiveAccount({ username: team.name, avatarUrl: team.avatarUrl }); - } else if (user) { - setActiveAccount({ - username: user.username, - avatarUrl: user.avatarUrl, - }); - } - }, [state.activeTeam, state.activeTeamInfo, dashboard.teams, user]); - - const inTeamContext = - activeAccount && user && activeAccount.username !== user.username; - - const folders = dashboard.allCollections || []; - - // context menu for folders - const [menuVisible, setMenuVisibility] = React.useState(true); - const [menuPosition, setMenuPosition] = React.useState({ - x: null, - y: null, - }); - const [ - menuFolder, - setMenuFolder, - ] = React.useState(null); - const [isRenamingFolder, setRenamingFolder] = React.useState(false); - const [newFolderPath, setNewFolderPath] = React.useState(null); - - const menuState = { - menuFolder, - setMenuFolder, - setMenuVisibility, - menuPosition, - setMenuPosition, - isRenamingFolder, - setRenamingFolder, - newFolderPath, - setNewFolderPath, - }; - - return ( - - - - - - - - - - - - - - - - - - - - - {visible && ( - - )} - - - - ); -}; - -// I hate this! but we need this until I refactor how -// components are structured — Sid -// https://linear.app/issue/CSB-118 -const linkStyles = { - width: '100%', - height: '100%', - display: 'flex', - alignItems: 'center', - paddingLeft: 8, - paddingRight: 8, - flexShrink: 0, -}; - -const canNotAcceptSandboxes: PageTypes[] = ['home', 'recents']; -const canNotAcceptFolders: PageTypes[] = [ - 'home', - 'recents', - 'drafts', - 'templates', -]; - -const isSamePath = ( - draggedItem: DragItemType, - currentPage: PageTypes, - dropPath: string -) => { - if (!draggedItem) return false; - - if ( - draggedItem.type === 'sandbox' && - draggedItem.sandbox.collection?.path === dropPath - ) { - return true; - } - - if (draggedItem.type === 'template' && currentPage === 'templates') { - return true; - } - - if ( - draggedItem.type === 'folder' && - (draggedItem.path === dropPath || draggedItem.parent === dropPath) - ) { - return true; - } - - return false; -}; - -interface RowItemProps { - name: string; - path: string; - icon: IconNames; - page: PageTypes; - setFoldersVisibility?: (val: boolean) => void; - folderPath?: string; - style?: React.CSSProperties; -} - -const RowItem: React.FC = ({ - name, - path, - folderPath = path, - page, - icon, - setFoldersVisibility = null, - ...props -}) => { - const accepts: Array<'sandbox' | 'folder' | 'template'> = []; - if (!canNotAcceptSandboxes.includes(page)) { - accepts.push('template'); - accepts.push('sandbox'); - } - if (!canNotAcceptFolders.includes(page)) accepts.push('folder'); - - const usedPath = folderPath || path; - const [{ canDrop, isOver, isDragging }, dropRef] = useDrop({ - accept: accepts, - drop: item => ({ - page, - path: usedPath, - isSamePath: isSamePath(item, page, usedPath), - }), - collect: monitor => ({ - isOver: monitor.isOver(), - canDrop: - monitor.canDrop() && !isSamePath(monitor.getItem(), page, usedPath), - isDragging: !!monitor.getItem(), - }), - }); - - const { onSidebarToggle } = React.useContext(SidebarContext); - - const linkTo: string = path; - - const location = useLocation(); - const isCurrentLink = linkTo.replace(/\?.*/, '') === location.pathname; - const history = useHistory(); - - /** Toggle nested folders when user - * is drags an item over a folder after a treshold - * We open All Sandboxes instantly because that's the root - * and you can't drop anything in it - */ - const HOVER_THRESHOLD = name === 'All Sandboxes' ? 0 : 500; // ms - const isOverCache = React.useRef(false); - - React.useEffect(() => { - if (!isOver) isOverCache.current = false; - else isOverCache.current = true; - - const handler = () => { - if (isOverCache.current && setFoldersVisibility) { - setFoldersVisibility(true); - } - }; - - const timer = window.setTimeout(handler, HOVER_THRESHOLD); - return () => window.clearTimeout(timer); - }, [isOver, setFoldersVisibility, HOVER_THRESHOLD]); - - return ( - theme.speeds[4], - a: { - ':focus': { - // focus state is handled by ListAction:focus-within - outline: 'none', - }, - }, - }, - props.style || {} - ) - )} - > - {props.children || ( - { - if (event.keyCode === ENTER) { - history.push(linkTo, { focus: 'FIRST_ITEM' }); - } - }} - > - - - - {name} - - )} - - ); -}; - -interface NestableRowItemProps { - name: string; - folderPath: string; - path: string; - folders: DashboardBaseFolder[]; -} - -const NestableRowItem: React.FC = ({ - name, - path, - folderPath, - folders, -}) => { - const { actions, state } = useOvermind(); - - const { - menuState: { - menuFolder, - setMenuFolder, - setMenuVisibility, - setMenuPosition, - isRenamingFolder, - setRenamingFolder, - newFolderPath, - setNewFolderPath, - }, - } = React.useContext(SidebarContext); - - const [foldersVisible, setFoldersVisibility] = React.useState(false); - - let hasNewNestedFolder = false; - if (newFolderPath !== null) { - const newFolderParent = newFolderPath.replace('/__NEW__', ''); - if (name === 'All Sandboxes') { - hasNewNestedFolder = true; - } else if (newFolderParent.length && folderPath.includes(newFolderParent)) { - hasNewNestedFolder = true; - } - } - - const location = useLocation(); - const currentFolderLocationPath = dashboardUrls.allSandboxes(folderPath); - React.useEffect(() => { - // Auto open folder in the sidebar if it's opened - const pathName = location.pathname; - const prefixCheck = - folderPath === '/' - ? currentFolderLocationPath - : currentFolderLocationPath + '/'; - - if (pathName.startsWith(prefixCheck) && !foldersVisible) { - setFoldersVisibility(true); - } - - // We don't want to recalculate after mount - // eslint-disable-next-line - }, [location.pathname, currentFolderLocationPath, setFoldersVisibility]); - - React.useEffect(() => { - if (hasNewNestedFolder) setFoldersVisibility(true); - }, [hasNewNestedFolder]); - - const onContextMenu = event => { - event.preventDefault(); - setMenuVisibility(true); - setMenuFolder({ name, path: folderPath }); - setMenuPosition({ x: event.clientX, y: event.clientY }); - }; - - let subFolders: DashboardBaseFolder[]; - if (name === 'All Sandboxes') { - subFolders = folders.filter(folder => { - if (folder.path === newFolderPath) { - return newFolderPath.replace('/__NEW__', '') === ''; - } - return !folder.parent; - }); - } else { - subFolders = folders.filter(folder => { - const parentPath = folder.path - .split('/') - .slice(0, -1) - .join('/'); - - return parentPath === folderPath; - }); - } - - const nestingLevel = - folderPath === '/' ? 0 : folderPath.split('/').length - 1; - const history = useHistory(); - - /* Rename logic */ - const isRenaming = isRenamingFolder && menuFolder.path === folderPath; - const isNewFolder = newFolderPath === folderPath; - const [newName, setNewName] = React.useState(name); - - const onChange = (event: React.ChangeEvent) => { - setNewName(event.target.value); - }; - const onInputKeyDown = (event: React.KeyboardEvent) => { - if (event.keyCode === ESC) { - // Reset value and exit without saving - setNewName(name); - setRenamingFolder(false); - setNewFolderPath(null); - } - }; - - const onSubmit = async (event?: React.FormEvent) => { - if (event) event.preventDefault(); - - if (name === newName) { - // nothing to do here - } else if (isNewFolder) { - if (newName) { - const sanitizedPath = folderPath.replace('__NEW__', newName); - await actions.dashboard.createFolder(sanitizedPath); - track('Dashboard - Create Directory', { - source: 'Sidebar', - dashboardVersion: 2, - folderPath: sanitizedPath, - }); - } - } else { - const newPath = join(dirname(folderPath), newName); - await actions.dashboard.renameFolder({ - path: folderPath, - newPath, - teamId: state.activeTeam, - newTeamId: state.activeTeam, - }); - - track('Dashboard - Rename Folder', { - source: 'Sidebar', - dashboardVersion: 2, - }); - - if (currentFolderLocationPath === location.pathname) { - // if this directory is opened - history.push(dashboardUrls.allSandboxes(newPath, state.activeTeam)); - } - } - - setNewFolderPath(null); - return setRenamingFolder(false); - }; - - const onInputBlur = () => { - // save value when you click outside or tab away - setRenamingFolder(false); - setNewFolderPath(null); - onSubmit(); - }; - - const folderUrl = dashboardUrls.allSandboxes(folderPath, state.activeTeam); - - return ( - <> - - history.push(folderUrl)} - onContextMenu={onContextMenu} - onKeyDown={event => { - if (event.keyCode === ENTER && !isRenaming && !isNewFolder) { - history.push(folderUrl, { - focus: 'FIRST_ITEM', - }); - } - }} - tabIndex={0} - style={{ - ...linkStyles, - paddingLeft: nestingLevel * 16, - }} - > - {subFolders.length ? ( - { - setFoldersVisibility(!foldersVisible); - event.stopPropagation(); - }} - css={css({ - width: 5, - height: '100%', - borderRadius: 0, - svg: { - transform: foldersVisible ? 'rotate(0deg)' : 'rotate(-90deg)', - transition: 'transform ease-in-out', - transitionDuration: theme => theme.speeds[2], - }, - })} - /> - ) : ( - - )} - - - - - - {isRenaming || isNewFolder ? ( -
- -
- ) : ( - - {name} - - )} -
- -
- - - {foldersVisible && ( - - {orderBy(subFolders, 'name') - .sort(a => 1) - .map(folder => ( - - ))} - - )} - - - ); -}; diff --git a/packages/app/src/app/pages/NewDashboard/index.tsx b/packages/app/src/app/pages/NewDashboard/index.tsx deleted file mode 100644 index 80c38e98f81..00000000000 --- a/packages/app/src/app/pages/NewDashboard/index.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import { signInPageUrl } from '@codesandbox/common/lib/utils/url-generator'; -import React, { FunctionComponent, useEffect } from 'react'; -import { Redirect, useLocation } from 'react-router-dom'; -import { DndProvider } from 'react-dnd'; -import Media from 'react-media'; -import Backend from 'react-dnd-html5-backend'; -import { useOvermind } from 'app/overmind'; -import { - ThemeProvider, - Stack, - Element, - SkipNav, -} from '@codesandbox/components'; -import { createGlobalStyle, useTheme } from 'styled-components'; -import css from '@styled-system/css'; - -import { Header } from './Header'; -import { Sidebar } from './Sidebar'; -import { SIDEBAR_WIDTH } from './Sidebar/constants'; -import { Content } from './Content'; - -const GlobalStyles = createGlobalStyle({ - body: { overflow: 'hidden' }, -}); - -export const Dashboard: FunctionComponent = () => { - const { - state: { hasLogIn }, - actions, - } = useOvermind(); - - // only used for mobile - const [sidebarVisible, setSidebarVisibility] = React.useState(false); - const onSidebarToggle = React.useCallback( - () => setSidebarVisibility(s => !s), - [setSidebarVisibility] - ); - const theme = useTheme() as any; - - const location = useLocation(); - useEffect(() => { - const searchParams = new URLSearchParams(location.search); - if (searchParams.get('workspace')) { - actions.setActiveTeam({ id: searchParams.get('workspace') }); - } - }, [location.search, actions]); - - if (!hasLogIn) { - return ; - } - - return ( - - - - - -
- - - {match => - match ? ( - - ) : ( - - { - /* do nothing */ - }} - style={{ - // We set sidebar as absolute so that content can - // take 100% width, this helps us enable dragging - // sandboxes onto the sidebar more freely. - position: 'absolute', - height: 'calc(100% - 48px)', - }} - /> - - ) - } - - - - - - - - - - ); -}; diff --git a/packages/app/src/app/pages/NewDashboard/queries.ts b/packages/app/src/app/pages/NewDashboard/queries.ts deleted file mode 100644 index f5c799c018f..00000000000 --- a/packages/app/src/app/pages/NewDashboard/queries.ts +++ /dev/null @@ -1,276 +0,0 @@ -// import { client } from 'app/graphql/client'; -// import { -// AddToCollectionMutation, -// AddToCollectionMutationVariables, -// DeleteSandboxesMutation, -// DeleteSandboxesMutationVariables, -// DeletedSandboxesQuery, -// DeletedSandboxesQueryVariables, -// PathedSandboxesQuery, -// PathedSandboxesQueryVariables, -// PermanentlyDeleteSandboxesMutation, -// PermanentlyDeleteSandboxesMutationVariables, -// } from 'app/graphql/types'; -// import gql from 'graphql-tag'; -// import immer from 'immer'; - -// export const PATHED_SANDBOXES_FOLDER_QUERY = gql` -// query PathedSandboxesFolders($teamId: ID) { -// me { -// collections(teamId: $teamId) { -// ...SidebarCollection -// } -// } -// } -// ${SIDEBAR_COLLECTION_FRAGMENT} -// `; - -// export const PATHED_SANDBOXES_CONTENT_QUERY = gql` -// query PathedSandboxes($path: String!, $teamId: ID) { -// me { -// collections(teamId: $teamId) { -// ...SidebarCollection -// } -// collection(path: $path, teamId: $teamId) { -// id -// path -// sandboxes { -// ...Sandbox -// } -// } -// } -// } -// ${SANDBOX_FRAGMENT} -// ${SIDEBAR_COLLECTION_FRAGMENT} -// `; - -// export const RECENT_SANDBOXES_CONTENT_QUERY = gql` -// query RecentSandboxes($orderField: String!, $orderDirection: Direction!) { -// me { -// sandboxes( -// limit: 7 -// orderBy: { field: $orderField, direction: $orderDirection } -// ) { -// ...Sandbox -// } -// } -// } -// ${SANDBOX_FRAGMENT} -// `; - -// export const RECENT_SANDBOXES_PAGE_QUERY = gql` -// query RecentSandboxes($orderField: String!, $orderDirection: Direction!) { -// me { -// sandboxes( -// limit: 50 -// orderBy: { field: $orderField, direction: $orderDirection } -// ) { -// ...Sandbox -// } -// } -// } -// ${SANDBOX_FRAGMENT} -// `; - -// export const SEARCH_SANDBOXES_QUERY = gql` -// query SearchSandboxes { -// me { -// sandboxes(orderBy: { field: "updated_at", direction: DESC }) { -// ...Sandbox -// } -// } -// } -// ${SANDBOX_FRAGMENT} -// `; - -// export const DELETED_SANDBOXES_CONTENT_QUERY = gql` -// query DeletedSandboxes { -// me { -// sandboxes( -// showDeleted: true -// orderBy: { field: "updated_at", direction: DESC } -// ) { -// ...Sandbox -// } -// } -// } -// ${SANDBOX_FRAGMENT} -// `; - -// export function addSandboxesToFolder( -// selectedSandboxes, -// path: string, -// teamId: string | null -// ) { -// return client.mutate< -// AddToCollectionMutation, -// AddToCollectionMutationVariables -// >({ -// mutation: ADD_SANDBOXES_TO_FOLDER_MUTATION, -// variables: { -// sandboxIds: selectedSandboxes, -// teamId, -// collectionPath: path, -// }, -// optimisticResponse: { -// __typename: 'RootMutationType', -// addToCollection: { -// __typename: 'Collection', -// // We keep this empty, because it will be loaded later regardless. We -// // just want the main directory to update immediately -// sandboxes: [], -// }, -// }, - -// refetchQueries: ['PathedSandboxes'], -// }); -// } - -// export function undeleteSandboxes(selectedSandboxes) { -// client.mutate({ -// mutation: ADD_SANDBOXES_TO_FOLDER_MUTATION, -// // @ts-ignore -// variables: { -// sandboxIds: selectedSandboxes.toJS -// ? selectedSandboxes.toJS() -// : selectedSandboxes, -// collectionPath: '/', -// }, -// optimisticResponse: { -// __typename: 'RootMutationType', -// addToCollection: { -// __typename: 'Collection', -// // We keep this empty, because it will be loaded later regardless. We -// // just want the main directory to update immediately -// sandboxes: [], -// }, -// }, - -// refetchQueries: ['DeletedSandboxes'], -// }); -// } - -// export function permanentlyDeleteSandboxes(selectedSandboxes: string[]) { -// return client.mutate< -// PermanentlyDeleteSandboxesMutation, -// PermanentlyDeleteSandboxesMutationVariables -// >({ -// mutation: PERMANENTLY_DELETE_SANDBOXES_MUTATION, -// variables: { -// sandboxIds: selectedSandboxes, -// }, -// update: cache => { -// try { -// const oldDeleteCache = cache.readQuery< -// DeletedSandboxesQuery, -// DeletedSandboxesQueryVariables -// >({ -// query: DELETED_SANDBOXES_CONTENT_QUERY, -// }); - -// const newDeleteCache = { -// ...oldDeleteCache, -// me: { -// ...(oldDeleteCache && oldDeleteCache.me ? oldDeleteCache.me : null), -// sandboxes: (oldDeleteCache?.me?.sandboxes || []).filter( -// x => !selectedSandboxes.includes(x.id) -// ), -// }, -// }; - -// cache.writeQuery({ -// query: DELETED_SANDBOXES_CONTENT_QUERY, -// data: newDeleteCache, -// }); -// } catch (e) { -// // cache doesn't exist, no biggie! -// } -// }, -// }); -// } - -// export function deleteSandboxes(selectedSandboxes, collections = []) { -// client.mutate({ -// mutation: DELETE_SANDBOXES_MUTATION, -// variables: { -// sandboxIds: selectedSandboxes.toJS -// ? selectedSandboxes.toJS() -// : selectedSandboxes, -// }, -// refetchQueries: [ -// 'DeletedSandboxes', -// 'PathedSandboxes', -// 'RecentSandboxes', -// 'SearchSandboxes', -// ], -// update: cache => { -// if (collections) { -// collections.forEach(({ path, teamId }) => { -// try { -// const variables = { -// path, -// teamId, -// }; - -// const oldFolderCacheData = cache.readQuery< -// PathedSandboxesQuery, -// PathedSandboxesQueryVariables -// >({ -// query: PATHED_SANDBOXES_CONTENT_QUERY, -// variables, -// }); - -// const data = immer(oldFolderCacheData, draft => { -// if ( -// !draft?.me?.collection || -// !oldFolderCacheData?.me?.collection?.sandboxes -// ) { -// return; -// } -// draft.me.collection.sandboxes = oldFolderCacheData.me.collection.sandboxes.filter( -// x => !selectedSandboxes.includes(x?.id) -// ); -// }); - -// if (data) { -// cache.writeQuery< -// PathedSandboxesQuery, -// PathedSandboxesQueryVariables -// >({ -// query: PATHED_SANDBOXES_CONTENT_QUERY, -// variables, -// data, -// }); -// } -// } catch (e) { -// // cache doesn't exist, no biggie! -// } -// }); -// } -// }, -// }); -// } - -// export function setSandboxesPrivacy( -// selectedSandboxes: string[], -// privacy: 0 | 1 | 2 -// ) { -// client.mutate({ -// mutation: SET_SANDBOXES_PRIVACY_MUTATION, -// variables: { -// sandboxIds: selectedSandboxes, -// privacy, -// }, -// }); -// } - -// export const TEAM_QUERY = gql` -// query Team($id: ID!) { -// me { -// team(id: $id) { -// ...Team -// } -// } -// } -// ${TEAM_FRAGMENT} -// `; diff --git a/packages/app/src/app/pages/NewDashboard/utils/__snapshots__/get-direct-children.test.js.snap b/packages/app/src/app/pages/NewDashboard/utils/__snapshots__/get-direct-children.test.js.snap deleted file mode 100644 index b9eb5efc561..00000000000 --- a/packages/app/src/app/pages/NewDashboard/utils/__snapshots__/get-direct-children.test.js.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`get-direct-children works with deeper paths 1`] = ` -Set { - "test2", - "test3", -} -`; - -exports[`get-direct-children works with root path 1`] = ` -Set { - "test", - "test2", -} -`; - -exports[`get-direct-children works with sub paths 1`] = ` -Set { - "test2", -} -`; diff --git a/packages/app/src/app/pages/NewDashboard/utils/get-child-collections.js b/packages/app/src/app/pages/NewDashboard/utils/get-child-collections.js deleted file mode 100644 index c74b87578a4..00000000000 --- a/packages/app/src/app/pages/NewDashboard/utils/get-child-collections.js +++ /dev/null @@ -1,17 +0,0 @@ -import getDirectChildren from './get-direct-children'; - -export default function getChildCollections(folders, path = '/') { - const foldersByPath = folders.reduce( - (pathedFolders, folder) => ({ - ...pathedFolders, - [folder.path]: folder, - }), - {} - ); - - return { - children: getDirectChildren(path, folders), - folders, - foldersByPath, - }; -} diff --git a/packages/app/src/app/pages/NewDashboard/utils/get-direct-children.js b/packages/app/src/app/pages/NewDashboard/utils/get-direct-children.js deleted file mode 100644 index 01bc04df70f..00000000000 --- a/packages/app/src/app/pages/NewDashboard/utils/get-direct-children.js +++ /dev/null @@ -1,37 +0,0 @@ -function addSlash(path: string) { - if (path.endsWith('/')) { - return path; - } - - return path + '/'; -} - -export default function getDirectChildren( - currentPath: string, - children: Array<{ path: string }> -): Set { - const usedChildren = new Set(); - - children.forEach(c => { - const { path } = c; - - const normalizedPath = addSlash(path); - const normalizedCurrentPath = addSlash(currentPath); - const basePath = normalizedPath.replace(normalizedCurrentPath, ''); - - if (basePath === normalizedPath) { - return undefined; - } - const normalizedBasePath = addSlash(basePath); - - const directChildPart = normalizedBasePath.match(/(.*?)\//); - - if (directChildPart && directChildPart[1]) { - usedChildren.add(directChildPart[1]); - } - - return undefined; - }); - - return usedChildren; -} diff --git a/packages/app/src/app/pages/NewDashboard/utils/get-direct-children.test.js b/packages/app/src/app/pages/NewDashboard/utils/get-direct-children.test.js deleted file mode 100644 index eec3b5ac19d..00000000000 --- a/packages/app/src/app/pages/NewDashboard/utils/get-direct-children.test.js +++ /dev/null @@ -1,33 +0,0 @@ -import getDirectChildren from './get-direct-children'; - -describe('get-direct-children', () => { - const defaultItems = [ - { path: '/test' }, - { path: '/test/test2' }, - { path: '/test2' }, - ]; - - it('works with root path', () => { - const root = '/'; - - expect(getDirectChildren(root, defaultItems)).toMatchSnapshot(); - }); - - it('works with sub paths', () => { - const root = '/test'; - - expect(getDirectChildren(root, defaultItems)).toMatchSnapshot(); - }); - - it('works with deeper paths', () => { - const items = [ - { path: '/test/test2/test3' }, - { path: '/test/test2' }, - { path: '/test/test3' }, - { path: '/test/test2/test4' }, - { path: '/test/test2/test3' }, - ]; - - expect(getDirectChildren('/test', items)).toMatchSnapshot(); - }); -}); diff --git a/packages/app/src/app/pages/NewDashboard/utils/get-most-used-template.js b/packages/app/src/app/pages/NewDashboard/utils/get-most-used-template.js deleted file mode 100644 index a802bc26b05..00000000000 --- a/packages/app/src/app/pages/NewDashboard/utils/get-most-used-template.js +++ /dev/null @@ -1,26 +0,0 @@ -import { countBy } from 'lodash-es'; -import getTemplate from '@codesandbox/common/lib/templates'; - -export default function getMostUsedTemplate(sandboxes) { - const countedByTemplates = countBy(sandboxes, s => s.source.template); - const mostUsedTemplateInfo = Object.keys(countedByTemplates).reduce( - (prev, template) => { - const count = countedByTemplates[template]; - if (count > prev.count) { - return { - count, - template, - }; - } - - return prev; - }, - { count: 0, template: '' } - ); - - if (mostUsedTemplateInfo.count > 0) { - return getTemplate(mostUsedTemplateInfo.template); - } - - return null; -} diff --git a/packages/app/src/app/pages/index.tsx b/packages/app/src/app/pages/index.tsx index cb0372c9549..624fbfa37cc 100644 --- a/packages/app/src/app/pages/index.tsx +++ b/packages/app/src/app/pages/index.tsx @@ -11,10 +11,9 @@ import { CreateSandboxModal } from 'app/components/CreateNewSandbox/CreateSandbo import { ErrorBoundary } from './common/ErrorBoundary'; import { Modals } from './common/Modals'; -import { Dashboard } from './Dashboard'; import { DevAuthPage } from './DevAuth'; import { Container, Content } from './elements'; -import { Dashboard as NewDashboard } from './NewDashboard'; +import { Dashboard } from './Dashboard'; import { Sandbox } from './Sandbox'; const routeDebugger = _debug('cs:app:router'); @@ -135,7 +134,7 @@ const RoutesComponent: React.FC = () => { /> - + diff --git a/packages/common/src/components/AutosizeInput/__snapshots__/index.test.tsx.snap b/packages/common/src/components/AutosizeInput/__snapshots__/index.test.tsx.snap deleted file mode 100644 index c3e62515a8d..00000000000 --- a/packages/common/src/components/AutosizeInput/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` rendering renders correctly 1`] = `ReactWrapper {}`; diff --git a/packages/common/src/components/AutosizeInput/index.stories.tsx b/packages/common/src/components/AutosizeInput/index.stories.tsx deleted file mode 100644 index 8311e1047f6..00000000000 --- a/packages/common/src/components/AutosizeInput/index.stories.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import { storiesOf } from '@storybook/react'; -import AutosizeInput from '.'; - -const stories = storiesOf('components/Input', module); - -stories.add('Basic AutosizeInput', () => ( - -)); diff --git a/packages/common/src/components/AutosizeInput/index.test.tsx b/packages/common/src/components/AutosizeInput/index.test.tsx deleted file mode 100644 index 87cd407970e..00000000000 --- a/packages/common/src/components/AutosizeInput/index.test.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import 'jest-styled-components'; -import React from 'react'; -import mountWithTheme from '../../test/themeMount'; -import AutosizeInput from '.'; - -describe(' rendering', () => { - it('renders correctly', () => { - expect(mountWithTheme()).toMatchSnapshot(); - }); -}); diff --git a/packages/common/src/components/AutosizeInput/index.tsx b/packages/common/src/components/AutosizeInput/index.tsx deleted file mode 100644 index 379e1471148..00000000000 --- a/packages/common/src/components/AutosizeInput/index.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import styled from 'styled-components'; -import AutosizeInput from 'react-input-autosize'; -import { styles } from '../Input'; - -export default styled(AutosizeInput)` - input { - ${styles}; - } -`; diff --git a/packages/common/src/components/AutosizeTextArea/__snapshots__/index.test.tsx.snap b/packages/common/src/components/AutosizeTextArea/__snapshots__/index.test.tsx.snap deleted file mode 100644 index 9e70bfdcb07..00000000000 --- a/packages/common/src/components/AutosizeTextArea/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` rendering renders correctly 1`] = `ReactWrapper {}`; diff --git a/packages/common/src/components/AutosizeTextArea/index.stories.tsx b/packages/common/src/components/AutosizeTextArea/index.stories.tsx deleted file mode 100644 index 3fb37a0098c..00000000000 --- a/packages/common/src/components/AutosizeTextArea/index.stories.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react'; -import { storiesOf } from '@storybook/react'; -import AutosizeTextArea from '.'; - -const stories = storiesOf('components/Input', module); -stories.add('Basic AutosizeTextArea', () => ( - -)); diff --git a/packages/common/src/components/AutosizeTextArea/index.test.tsx b/packages/common/src/components/AutosizeTextArea/index.test.tsx deleted file mode 100644 index 51325458797..00000000000 --- a/packages/common/src/components/AutosizeTextArea/index.test.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import 'jest-styled-components'; -import React from 'react'; -import mountWithTheme from '../../test/themeMount'; -import AutosizeTextArea from '.'; - -describe(' rendering', () => { - it('renders correctly', () => { - expect(mountWithTheme()).toMatchSnapshot(); - }); -}); diff --git a/packages/common/src/components/AutosizeTextArea/index.tsx b/packages/common/src/components/AutosizeTextArea/index.tsx deleted file mode 100644 index eee68848af3..00000000000 --- a/packages/common/src/components/AutosizeTextArea/index.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import AutosizeInput from 'react-textarea-autosize'; -import Input from '../Input'; - -export default Input.withComponent(AutosizeInput); diff --git a/packages/common/src/components/Checkbox/__snapshots__/index.test.tsx.snap b/packages/common/src/components/Checkbox/__snapshots__/index.test.tsx.snap deleted file mode 100644 index 2e6f1e65ef7..00000000000 --- a/packages/common/src/components/Checkbox/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,5 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` rendering checkbox checked 1`] = `ReactWrapper {}`; - -exports[` rendering no props 1`] = `ReactWrapper {}`; diff --git a/packages/common/src/components/Checkbox/index.stories.tsx b/packages/common/src/components/Checkbox/index.stories.tsx deleted file mode 100644 index e539d662d61..00000000000 --- a/packages/common/src/components/Checkbox/index.stories.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/* eslint-disable jsx-a11y/label-has-associated-control */ -import React from 'react'; -import { storiesOf } from '@storybook/react'; -import { action } from '@storybook/addon-actions'; -import { Checkbox } from '.'; - -const stories = storiesOf('components/Checkbox', module); - -stories - .add('Basic Checkbox', () => ( - <> - - - - )) - .add('Checked Checkbox', () => ( - <> - - - - )); diff --git a/packages/common/src/components/Checkbox/index.test.tsx b/packages/common/src/components/Checkbox/index.test.tsx deleted file mode 100644 index 143d1e8db1b..00000000000 --- a/packages/common/src/components/Checkbox/index.test.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import 'jest-styled-components'; -import React from 'react'; -import mountWithTheme from '../../test/themeMount'; -import { Checkbox } from '.'; - -describe(' rendering', () => { - it('no props', () => { - const wrapper = mountWithTheme(); - expect(wrapper).toMatchSnapshot(); - }); - it('checkbox checked', () => { - const wrapper = mountWithTheme(); - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/packages/common/src/components/Checkbox/index.tsx b/packages/common/src/components/Checkbox/index.tsx deleted file mode 100644 index f557ca3db45..00000000000 --- a/packages/common/src/components/Checkbox/index.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import styled from 'styled-components'; - -type Props = { - checked?: boolean; - style?: React.CSSProperties; - onChange?: () => void; - onClick?: () => void; - id?: string; -}; - -const svg = - "data:image/svg+xml;utf8,"; - -const CheckBoxStyled = styled.input` - background-image: none; - border: 2px solid transparent; - background: ${props => - props.theme.light ? 'rgba(0, 0, 0, 0.3)' : 'rgba(255, 255, 255, 0.3)'} - url('') no-repeat 50%/10px; - - box-shadow: none; - display: inline-block; - border-radius: 3.5px; - width: 16px; - height: 16px; - vertical-align: middle; - margin-right: 0.75rem; - transition: 0.15s ease all; - appearance: none; - - &:focus, - &:active { - border-color: ${props => props.theme.shySecondary}; - } - - &:checked { - background: ${props => props.theme.shySecondary} url('') no-repeat 50%/10px; - border-color: ${props => props.theme.shySecondary}; - background-image: url("${encodeURIComponent(svg)}"); - } -`; - -export const Checkbox = (props: Props) => ( - -); diff --git a/packages/common/src/components/CustomTemplate/__snapshots__/index.test.tsx.snap b/packages/common/src/components/CustomTemplate/__snapshots__/index.test.tsx.snap deleted file mode 100644 index dd7f1074864..00000000000 --- a/packages/common/src/components/CustomTemplate/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,9 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` rendering Default 1`] = `ReactWrapper {}`; - -exports[` rendering No Description 1`] = `ReactWrapper {}`; - -exports[` rendering No Tags 1`] = `ReactWrapper {}`; - -exports[` rendering No Title 1`] = `ReactWrapper {}`; diff --git a/packages/common/src/components/CustomTemplate/elements.ts b/packages/common/src/components/CustomTemplate/elements.ts deleted file mode 100644 index 04ace88698e..00000000000 --- a/packages/common/src/components/CustomTemplate/elements.ts +++ /dev/null @@ -1,76 +0,0 @@ -import styled, { css } from 'styled-components'; -import { Overlay } from '../SandboxCard/elements'; - -export const Border = styled.div<{ color?: string }>` - ${({ color = `none` }) => css` - position: relative; - top: -4px; - width: 100%; - height: 4px; - background: ${color}; - `} -`; - -export const TemplateTitle = styled.span` - display: block; - width: 100%; - margin: 6px 12px; - font-family: Poppins, Roboto, sans-serif; - font-size: 12px; - font-weight: 500; - text-align: left; -`; - -export const TemplateSubTitle = styled.span` - ${({ theme }) => css` - display: block; - width: 100%; - height: 16px; - padding: 0 12px; - margin-bottom: 6px; - color: ${theme.placeholder}; - font-size: 12px; - text-align: left; - line-height: 16px; - overflow: hidden; - text-overflow: ellipsis; - box-sizing: border-box; - `} -`; - -export const MyTemplate = styled.button<{ overlayHeight?: number }>` - ${({ theme, overlayHeight }) => css` - position: relative; - width: 203.5px; - min-width: 203.5px; - padding: 0; - border: 2px solid ${theme.background5}; - border-radius: 4px; - background: ${theme.background2}; - color: ${theme.lightText}; - cursor: pointer; - box-sizing: border-box; - overflow: hidden; - - &:focus { - border: 2px solid ${theme.secondary}; - outline: none; - } - - img { - display: block; - max-width: 100%; - } - - ${Overlay} { - height: ${overlayHeight}px; - text-align: left; - } - - &:hover { - ${Overlay} { - opacity: 1; - } - } - `} -`; diff --git a/packages/common/src/components/CustomTemplate/index.stories.tsx b/packages/common/src/components/CustomTemplate/index.stories.tsx deleted file mode 100644 index 9c3dd744a68..00000000000 --- a/packages/common/src/components/CustomTemplate/index.stories.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; -import { storiesOf } from '@storybook/react'; -import { object } from '@storybook/addon-knobs'; -import CustomTemplate from '.'; -import { sandbox } from '../SandboxCard/fixtures'; - -const template = (props = null) => ({ - id: '2321', - color: '#fff', - sandbox: sandbox(props), -}); - -const stories = storiesOf('components/CustomTemplate', module); -stories - .add('Default', () => ( - - )) - .add('No Title', () => ( - - )) - .add('No Description', () => ( - - )) - .add('No Tags', () => ( - - )); diff --git a/packages/common/src/components/CustomTemplate/index.test.tsx b/packages/common/src/components/CustomTemplate/index.test.tsx deleted file mode 100644 index f19fa7f2503..00000000000 --- a/packages/common/src/components/CustomTemplate/index.test.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import 'jest-styled-components'; -import React from 'react'; -import mountWithTheme from '../../test/themeMount'; -import CustomTemplate from '.'; -import { sandbox } from '../SandboxCard/fixtures'; - -const template = (props = null) => ({ - id: '2321', - color: '#fff', - sandbox: sandbox(props), -}); - -describe(' rendering', () => { - it('Default', () => - expect( - mountWithTheme() - ).toMatchSnapshot()); - it('No Title', () => - expect( - mountWithTheme() - ).toMatchSnapshot()); - it('No Description', () => - expect( - mountWithTheme( - - ) - ).toMatchSnapshot()); - it('No Tags', () => - expect( - mountWithTheme() - ).toMatchSnapshot()); -}); diff --git a/packages/common/src/components/CustomTemplate/index.tsx b/packages/common/src/components/CustomTemplate/index.tsx deleted file mode 100644 index 9e4994b6efd..00000000000 --- a/packages/common/src/components/CustomTemplate/index.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import React from 'react'; -import Tags from '../Tags'; -import { Overlay, SandboxDescription } from '../SandboxCard/elements'; -import { - Border, - TemplateTitle, - TemplateSubTitle, - MyTemplate, -} from './elements'; -import { getSandboxName } from '../../utils/get-sandbox-name'; - -interface Props { - template?: { - id: string; - color: string; - sandbox: { - id: string; - title: string; - alias: string; - description: string; - tags?: string[]; - }; - }; - i: number; - onClick?: () => void; -} -const BANNER = 'https://codesandbox.io/static/img/banner.png'; -const SCREENSHOT_API_URL = (id: string) => - `https://codesandbox.io/api/v1/sandboxes/${id}/screenshot.png`; -const CustomTemplate = ({ template, onClick, i }: Props) => { - if (!template) { - return ( - - loading - -
- Loading -
-
- ); - } - - const { sandbox } = template; - const title = getSandboxName(sandbox); - - return ( - - {title} - - {sandbox.description} - {sandbox.tags && } - - -
- {title} - {sandbox.description} -
-
- ); -}; - -export default CustomTemplate; diff --git a/packages/common/src/components/GridList/GridList.tsx b/packages/common/src/components/GridList/GridList.tsx deleted file mode 100644 index 15a27cc4429..00000000000 --- a/packages/common/src/components/GridList/GridList.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React, { cloneElement, Children, useState } from 'react'; -import { Group } from 'reakit/Group'; -import { useRoverState, Rover } from 'reakit/Rover'; -import { - Container, - Arrow, - CarrouselWrapper, - Carrousel, - ArrowButton, -} from './elements'; - -const chunk = (arr: any[], size: number): any[] => - Array.from({ length: Math.ceil(arr.length / size) }, (_, i) => - arr.slice(i * size, i * size + size) - ); - -export const GridList = ({ children, ...props }) => { - const [numberOfClick, setNumberOfClick] = useState(0); - const rover = useRoverState(); - const templates = chunk(children, 3); - - const move = (n: number) => { - setNumberOfClick(numberOfClicks => numberOfClicks + n); - }; - - return ( - - {numberOfClick > 0 ? ( - move(-1)} - > - - - ) : null} - - {templates.map((kids: any[], i: number) => ( - // eslint-disable-next-line react/no-array-index-key - - {kids.map((child: any[], idx: number) => ( - // eslint-disable-next-line react/no-array-index-key - - {itemProps => cloneElement(Children.only(child), itemProps)} - - ))} - - ))} - - {templates.length > 2 && templates.length - 2 !== numberOfClick && ( - move(1)} - next - > - - - )} - - ); -}; diff --git a/packages/common/src/components/GridList/Next.tsx b/packages/common/src/components/GridList/Next.tsx deleted file mode 100644 index a3754d5f215..00000000000 --- a/packages/common/src/components/GridList/Next.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; - -export const NextIcon = props => ( - - - -); diff --git a/packages/common/src/components/GridList/elements.ts b/packages/common/src/components/GridList/elements.ts deleted file mode 100644 index f3e3854c8d8..00000000000 --- a/packages/common/src/components/GridList/elements.ts +++ /dev/null @@ -1,59 +0,0 @@ -import styled, { css } from 'styled-components'; -import { NextIcon } from './Next'; - -export const Container = styled.div` - display: flex; - margin: 0 1.5rem; - overflow: hidden; - position: relative; - - > div { - &:first-child button { - padding-left: 0px; - } - } -`; - -export const ArrowButton = styled.button<{ next?: boolean }>` - display: flex; - align-items: center; - justify-content: center; - background: none; - border: none; - z-index: 10; - position: absolute; - top: 50%; - margin: 0; - transform: translateY(-50%); - - ${props => - props.next && - css` - left: auto; - right: 0.5rem; - `} -`; - -export const Arrow = styled(NextIcon)<{ next?: boolean }>` - transform: rotate(180deg); - - ${props => - props.next && - css` - transform: rotate(0deg); - `} -`; - -export const CarrouselWrapper = styled.div` - width: 50%; - flex-grow: 1; - flex-shrink: 0; - margin-bottom: 2rem; -`; - -export const Carrousel = styled.div<{ number: number }>` - transition: transform 200ms ease; - transform: ${props => `translateX(-${50 * props.number}%)`}; - display: flex; - width: 100%; -`; diff --git a/packages/common/src/components/GridList/index.ts b/packages/common/src/components/GridList/index.ts deleted file mode 100644 index 42d003a36f4..00000000000 --- a/packages/common/src/components/GridList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { GridList } from './GridList'; From 1dbeef1d5189a507cd97ae82d47c4305ae306ac5 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Thu, 16 Jul 2020 15:01:06 +0200 Subject: [PATCH 2/5] comment old dashboard imports --- .../Filters/FilterOptions/index.tsx | 2 +- .../Dashboard/Content/routes/All/index.tsx | 8 +-- .../Content/routes/All/useFilteredItems.ts | 2 +- .../Content/routes/Deleted/index.tsx | 8 +-- .../Dashboard/Content/routes/Drafts/index.tsx | 8 +-- .../Dashboard/Content/routes/Home/index.tsx | 8 +-- .../Dashboard/Content/routes/Recent/index.tsx | 8 +-- .../Content/routes/Repositories/index.tsx | 8 +-- .../routes/Repositories/useFilteredItems.ts | 2 +- .../Dashboard/Content/routes/Search/index.tsx | 8 +-- .../Content/routes/Settings/TeamSettings.tsx | 2 +- .../Content/routes/Templates/index.tsx | 8 +-- .../DirectoryPicker/TeamsPicker/index.tsx | 20 ++++-- .../DirectoryPicker/index.tsx | 6 +- .../Modals/MoveSandboxFolderModal/index.tsx | 42 +++++------ .../components/CommunityBadges/__index.tsx | 59 --------------- .../CommunityBadges/index.stories.tsx | 54 -------------- .../src/components/CommunityBadges/index.tsx | 72 ------------------- 18 files changed, 73 insertions(+), 252 deletions(-) delete mode 100644 packages/common/src/components/CommunityBadges/__index.tsx delete mode 100644 packages/common/src/components/CommunityBadges/index.stories.tsx delete mode 100644 packages/common/src/components/CommunityBadges/index.tsx diff --git a/packages/app/src/app/pages/Dashboard/Components/Filters/FilterOptions/index.tsx b/packages/app/src/app/pages/Dashboard/Components/Filters/FilterOptions/index.tsx index 95d45101cc7..b86204c91f9 100644 --- a/packages/app/src/app/pages/Dashboard/Components/Filters/FilterOptions/index.tsx +++ b/packages/app/src/app/pages/Dashboard/Components/Filters/FilterOptions/index.tsx @@ -7,7 +7,7 @@ import { orderBy, noop } from 'lodash-es'; import css from '@styled-system/css'; import { useOvermind } from 'app/overmind'; import { Text, Menu, Checkbox } from '@codesandbox/components'; -import { TemplateFilter } from 'app/pages/NewDashboard/Content/utils'; +import { TemplateFilter } from 'app/pages/Dashboard/Content/utils'; type Props = { possibleTemplates?: TemplateFilter[]; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/All/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/All/index.tsx index 29427fa13eb..85ed9d75740 100644 --- a/packages/app/src/app/pages/Dashboard/Content/routes/All/index.tsx +++ b/packages/app/src/app/pages/Dashboard/Content/routes/All/index.tsx @@ -2,10 +2,10 @@ import React from 'react'; import { Helmet } from 'react-helmet'; import { useParams, useHistory } from 'react-router-dom'; import { useOvermind } from 'app/overmind'; -import { Header } from 'app/pages/NewDashboard/Components/Header'; -import { SelectionProvider } from 'app/pages/NewDashboard/Components/Selection'; -import { VariableGrid } from 'app/pages/NewDashboard/Components/VariableGrid'; -import { DashboardGridItem, PageTypes } from 'app/pages/NewDashboard/types'; +import { Header } from 'app/pages/Dashboard/Components/Header'; +import { SelectionProvider } from 'app/pages/Dashboard/Components/Selection'; +import { VariableGrid } from 'app/pages/Dashboard/Components/VariableGrid'; +import { DashboardGridItem, PageTypes } from 'app/pages/Dashboard/types'; import { dashboard } from '@codesandbox/common/lib/utils/url-generator'; import { getPossibleTemplates } from '../../utils'; import { useFilteredItems } from './useFilteredItems'; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/All/useFilteredItems.ts b/packages/app/src/app/pages/Dashboard/Content/routes/All/useFilteredItems.ts index d57e0412ed4..206c3af1258 100644 --- a/packages/app/src/app/pages/Dashboard/Content/routes/All/useFilteredItems.ts +++ b/packages/app/src/app/pages/Dashboard/Content/routes/All/useFilteredItems.ts @@ -6,7 +6,7 @@ import { DashboardFolder, DashboardTemplate, DashboardSkeletonRow, -} from 'app/pages/NewDashboard/types'; +} from 'app/pages/Dashboard/types'; type Params = { path?: string; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Deleted/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Deleted/index.tsx index aa4b0d0cc78..482bdff29c0 100644 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Deleted/index.tsx +++ b/packages/app/src/app/pages/Dashboard/Content/routes/Deleted/index.tsx @@ -2,10 +2,10 @@ import React, { useEffect } from 'react'; import { Helmet } from 'react-helmet'; import { useOvermind } from 'app/overmind'; import { sandboxesTypes } from 'app/overmind/namespaces/dashboard/types'; -import { Header } from 'app/pages/NewDashboard/Components/Header'; -import { VariableGrid } from 'app/pages/NewDashboard/Components/VariableGrid'; -import { SelectionProvider } from 'app/pages/NewDashboard/Components/Selection'; -import { DashboardGridItem, PageTypes } from 'app/pages/NewDashboard/types'; +import { Header } from 'app/pages/Dashboard/Components/Header'; +import { VariableGrid } from 'app/pages/Dashboard/Components/VariableGrid'; +import { SelectionProvider } from 'app/pages/Dashboard/Components/Selection'; +import { DashboardGridItem, PageTypes } from 'app/pages/Dashboard/types'; import { SandboxFragmentDashboardFragment } from 'app/graphql/types'; import { getPossibleTemplates } from '../../utils'; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Drafts/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Drafts/index.tsx index c043c2967ee..67db0d4708e 100644 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Drafts/index.tsx +++ b/packages/app/src/app/pages/Dashboard/Content/routes/Drafts/index.tsx @@ -2,10 +2,10 @@ import React from 'react'; import { Helmet } from 'react-helmet'; import { useOvermind } from 'app/overmind'; import { sandboxesTypes } from 'app/overmind/namespaces/dashboard/types'; -import { Header } from 'app/pages/NewDashboard/Components/Header'; -import { VariableGrid } from 'app/pages/NewDashboard/Components/VariableGrid'; -import { SelectionProvider } from 'app/pages/NewDashboard/Components/Selection'; -import { DashboardGridItem, PageTypes } from 'app/pages/NewDashboard/types'; +import { Header } from 'app/pages/Dashboard/Components/Header'; +import { VariableGrid } from 'app/pages/Dashboard/Components/VariableGrid'; +import { SelectionProvider } from 'app/pages/Dashboard/Components/Selection'; +import { DashboardGridItem, PageTypes } from 'app/pages/Dashboard/types'; import { getPossibleTemplates } from '../../utils'; export const Drafts = () => { diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Home/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Home/index.tsx index 03b656dd9f4..4ce763f136f 100644 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Home/index.tsx +++ b/packages/app/src/app/pages/Dashboard/Content/routes/Home/index.tsx @@ -1,16 +1,16 @@ import React, { useEffect } from 'react'; import { useOvermind } from 'app/overmind'; import { sandboxesTypes } from 'app/overmind/namespaces/dashboard/types'; -import { Header } from 'app/pages/NewDashboard/Components/Header'; -import { VariableGrid } from 'app/pages/NewDashboard/Components/VariableGrid'; -import { SelectionProvider } from 'app/pages/NewDashboard/Components/Selection'; +import { Header } from 'app/pages/Dashboard/Components/Header'; +import { VariableGrid } from 'app/pages/Dashboard/Components/VariableGrid'; +import { SelectionProvider } from 'app/pages/Dashboard/Components/Selection'; import { dashboard as dashboardUrls } from '@codesandbox/common/lib/utils/url-generator'; import { Helmet } from 'react-helmet'; import { DashboardGridItem, DashboardTemplate, PageTypes, -} from 'app/pages/NewDashboard/types'; +} from 'app/pages/Dashboard/types'; export const Home = () => { const { diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Recent/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Recent/index.tsx index c571989fa20..bb25f7dd8e8 100644 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Recent/index.tsx +++ b/packages/app/src/app/pages/Dashboard/Content/routes/Recent/index.tsx @@ -1,16 +1,16 @@ import React from 'react'; import { Helmet } from 'react-helmet'; -import { SelectionProvider } from 'app/pages/NewDashboard/Components/Selection'; +import { SelectionProvider } from 'app/pages/Dashboard/Components/Selection'; import { useOvermind } from 'app/overmind'; import { sandboxesTypes } from 'app/overmind/namespaces/dashboard/types'; -import { Header } from 'app/pages/NewDashboard/Components/Header'; -import { VariableGrid } from 'app/pages/NewDashboard/Components/VariableGrid'; +import { Header } from 'app/pages/Dashboard/Components/Header'; +import { VariableGrid } from 'app/pages/Dashboard/Components/VariableGrid'; import { DashboardGridItem, DashboardHeader, DashboardSandbox, PageTypes, -} from 'app/pages/NewDashboard/types'; +} from 'app/pages/Dashboard/types'; import { getPossibleTemplates } from '../../utils'; export const Recent = () => { diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Repositories/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Repositories/index.tsx index 54e623d6b77..6d1dcdfaf8e 100644 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Repositories/index.tsx +++ b/packages/app/src/app/pages/Dashboard/Content/routes/Repositories/index.tsx @@ -2,14 +2,14 @@ import React from 'react'; import { Helmet } from 'react-helmet'; import { useParams } from 'react-router-dom'; import { useOvermind } from 'app/overmind'; -import { Header } from 'app/pages/NewDashboard/Components/Header'; -import { VariableGrid } from 'app/pages/NewDashboard/Components/VariableGrid'; +import { Header } from 'app/pages/Dashboard/Components/Header'; +import { VariableGrid } from 'app/pages/Dashboard/Components/VariableGrid'; import { DashboardGridItem, DashboardRepoSandbox, PageTypes, -} from 'app/pages/NewDashboard/types'; -import { SelectionProvider } from 'app/pages/NewDashboard/Components/Selection'; +} from 'app/pages/Dashboard/types'; +import { SelectionProvider } from 'app/pages/Dashboard/Components/Selection'; import { getPossibleTemplates } from '../../utils'; import { useFilteredItems } from './useFilteredItems'; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Repositories/useFilteredItems.ts b/packages/app/src/app/pages/Dashboard/Content/routes/Repositories/useFilteredItems.ts index 593bee57478..4fad7daf0ac 100644 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Repositories/useFilteredItems.ts +++ b/packages/app/src/app/pages/Dashboard/Content/routes/Repositories/useFilteredItems.ts @@ -1,7 +1,7 @@ import { useState, useEffect } from 'react'; import { compareDesc } from 'date-fns'; import { useOvermind } from 'app/overmind'; -import { DashboardGridItem } from 'app/pages/NewDashboard/types'; +import { DashboardGridItem } from 'app/pages/Dashboard/types'; type Params = { path?: string; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Search/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Search/index.tsx index 01c9b891fc0..6dbf110f6a4 100644 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Search/index.tsx +++ b/packages/app/src/app/pages/Dashboard/Content/routes/Search/index.tsx @@ -2,12 +2,12 @@ import { useOvermind } from 'app/overmind'; import { sandboxesTypes } from 'app/overmind/namespaces/dashboard/types'; import { Helmet } from 'react-helmet'; import Fuse from 'fuse.js'; -import { Header } from 'app/pages/NewDashboard/Components/Header'; -import { VariableGrid } from 'app/pages/NewDashboard/Components/VariableGrid'; -import { SelectionProvider } from 'app/pages/NewDashboard/Components/Selection'; +import { Header } from 'app/pages/Dashboard/Components/Header'; +import { VariableGrid } from 'app/pages/Dashboard/Components/VariableGrid'; +import { SelectionProvider } from 'app/pages/Dashboard/Components/Selection'; import React, { useEffect } from 'react'; import { useLocation } from 'react-router-dom'; -import { DashboardGridItem, PageTypes } from 'app/pages/NewDashboard/types'; +import { DashboardGridItem, PageTypes } from 'app/pages/Dashboard/types'; import { SandboxFragmentDashboardFragment } from 'app/graphql/types'; import { getPossibleTemplates } from '../../utils'; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Settings/TeamSettings.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Settings/TeamSettings.tsx index e08c94ed3f4..ea0569a7a7e 100644 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Settings/TeamSettings.tsx +++ b/packages/app/src/app/pages/Dashboard/Content/routes/Settings/TeamSettings.tsx @@ -13,7 +13,7 @@ import { } from '@codesandbox/components'; import css from '@styled-system/css'; import { UserSearchInput } from 'app/components/UserSearchInput'; -import { Header } from 'app/pages/NewDashboard/Components/Header'; +import { Header } from 'app/pages/Dashboard/Components/Header'; import { teamInviteLink } from '@codesandbox/common/lib/utils/url-generator'; import { sortBy } from 'lodash-es'; import { TeamAvatar } from 'app/components/TeamAvatar'; diff --git a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/index.tsx b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/index.tsx index bf1f1a98cc4..d4664ab964d 100644 --- a/packages/app/src/app/pages/Dashboard/Content/routes/Templates/index.tsx +++ b/packages/app/src/app/pages/Dashboard/Content/routes/Templates/index.tsx @@ -2,10 +2,10 @@ import { useOvermind } from 'app/overmind'; import { Helmet } from 'react-helmet'; import React, { useEffect } from 'react'; import { sandboxesTypes } from 'app/overmind/namespaces/dashboard/types'; -import { Header } from 'app/pages/NewDashboard/Components/Header'; -import { VariableGrid } from 'app/pages/NewDashboard/Components/VariableGrid'; -import { SelectionProvider } from 'app/pages/NewDashboard/Components/Selection'; -import { DashboardGridItem, PageTypes } from 'app/pages/NewDashboard/types'; +import { Header } from 'app/pages/Dashboard/Components/Header'; +import { VariableGrid } from 'app/pages/Dashboard/Components/VariableGrid'; +import { SelectionProvider } from 'app/pages/Dashboard/Components/Selection'; +import { DashboardGridItem, PageTypes } from 'app/pages/Dashboard/types'; import { TemplateFragmentDashboardFragment } from 'app/graphql/types'; import { getPossibleTemplates } from '../../utils'; diff --git a/packages/app/src/app/pages/common/Modals/MoveSandboxFolderModal/DirectoryPicker/TeamsPicker/index.tsx b/packages/app/src/app/pages/common/Modals/MoveSandboxFolderModal/DirectoryPicker/TeamsPicker/index.tsx index 719ee0df0b1..e38764a3eb1 100644 --- a/packages/app/src/app/pages/common/Modals/MoveSandboxFolderModal/DirectoryPicker/TeamsPicker/index.tsx +++ b/packages/app/src/app/pages/common/Modals/MoveSandboxFolderModal/DirectoryPicker/TeamsPicker/index.tsx @@ -1,13 +1,14 @@ -import { useQuery } from '@apollo/react-hooks'; +// import { useQuery } from '@apollo/react-hooks'; import React, { ComponentProps, FunctionComponent } from 'react'; -import { TEAMS_QUERY } from 'app/pages/Dashboard/queries'; -import { SandboxesItem } from 'app/pages/Dashboard/Sidebar/SandboxesItem'; +// import { TEAMS_QUERY } from 'app/pages/Dashboard/queries'; +// import { SandboxesItem } from 'app/pages/Dashboard/Sidebar/SandboxesItem'; import { TeamContainer, TeamName } from './elements'; type Props = Pick< - ComponentProps, + ComponentProps, + // , 'currentPath' | 'currentTeamId' | 'onSelect' >; export const TeamsPicker: FunctionComponent = ({ @@ -15,7 +16,12 @@ export const TeamsPicker: FunctionComponent = ({ currentTeamId, onSelect, }) => { - const { loading, error, data } = useQuery(TEAMS_QUERY); + // const { loading, error, data } = useQuery(TEAMS_QUERY); + const { loading, error, data } = { + data: { me: { teams: [] } }, + error: null, + loading: false, + }; if (loading || error) { return null; @@ -27,13 +33,13 @@ export const TeamsPicker: FunctionComponent = ({ {name} - + /> */} ))} diff --git a/packages/app/src/app/pages/common/Modals/MoveSandboxFolderModal/DirectoryPicker/index.tsx b/packages/app/src/app/pages/common/Modals/MoveSandboxFolderModal/DirectoryPicker/index.tsx index 2c4ec5119c9..da4f6c66720 100644 --- a/packages/app/src/app/pages/common/Modals/MoveSandboxFolderModal/DirectoryPicker/index.tsx +++ b/packages/app/src/app/pages/common/Modals/MoveSandboxFolderModal/DirectoryPicker/index.tsx @@ -1,6 +1,6 @@ import React, { ComponentProps, FunctionComponent } from 'react'; -import { SandboxesItem } from 'app/pages/Dashboard/Sidebar/SandboxesItem'; +// import { SandboxesItem } from 'app/pages/Dashboard/Sidebar/SandboxesItem'; import { TeamsPicker } from './TeamsPicker'; @@ -14,13 +14,13 @@ export const DirectoryPicker: FunctionComponent = ({ onSelect, }) => ( <> - + /> */} { const { - actions: { modalClosed, refetchSandboxInfo }, + actions: { modalClosed }, state: { editor: { currentSandbox }, }, } = useOvermind(); - const { collection, id, team } = currentSandbox || {}; + const { collection, team } = currentSandbox || {}; const [error, setError] = useState(undefined); const [loading, setLoading] = useState(false); const [path, setPath] = useState(collection?.path || '/'); @@ -33,26 +33,26 @@ export const MoveSandboxFolderModal: FunctionComponent = () => { setPath(newPath); }; - useEffect(() => { - if (!loading) { - return; - } + // useEffect(() => { + // if (!loading) { + // return; + // } - addSandboxesToFolder([id], path, teamId) - .then(() => { - refetchSandboxInfo(); + // addSandboxesToFolder([id], path, teamId) + // .then(() => { + // refetchSandboxInfo(); - setLoading(false); - modalClosed(); + // setLoading(false); + // modalClosed(); - track('Move Sandbox From Editor'); - }) - .catch(({ message }) => { - setError(message); + // track('Move Sandbox From Editor'); + // }) + // .catch(({ message }) => { + // setError(message); - setLoading(false); - }); - }, [id, loading, modalClosed, path, refetchSandboxInfo, teamId]); + // setLoading(false); + // }); + // }, [id, loading, modalClosed, path, refetchSandboxInfo, teamId]); return ( ( -
- -
-); - -describe(' rendering', () => { - templates.map(t => - it(`gold ${t}`, () => { - expect(mountWithTheme()).toMatchSnapshot(); - }) - ); - - templates.map(t => - it(`silver ${t}`, () => { - expect( - mountWithTheme() - ).toMatchSnapshot(); - }) - ); -}); diff --git a/packages/common/src/components/CommunityBadges/index.stories.tsx b/packages/common/src/components/CommunityBadges/index.stories.tsx deleted file mode 100644 index ea9f0817414..00000000000 --- a/packages/common/src/components/CommunityBadges/index.stories.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import React from 'react'; -import { storiesOf } from '@storybook/react'; -import CommunityBadge from '.'; - -const templates = [ - 'create-react-app', - 'vue-cli', - 'preact-cli', - 'svelte', - 'create-react-app-typescript', - 'angular-cli', - 'parcel', - 'cxjs', - '@dojo/cli-create-app', - 'gatsby', - 'nuxt', - 'next', - 'reason', - 'apollo', - 'sapper', - 'nest', - 'static', - 'styleguidist', -]; - -const FrameworkBadge = ({ template, sandboxNumber = 100 }) => ( -
- -
-); - -templates.map(t => - storiesOf('components/Community Badge/Gold', module).add(t, () => ( - - )) -); - -templates.map(t => - storiesOf('components/Community Badge/Silver', module).add(t, () => ( - - )) -); diff --git a/packages/common/src/components/CommunityBadges/index.tsx b/packages/common/src/components/CommunityBadges/index.tsx deleted file mode 100644 index ae4ae923496..00000000000 --- a/packages/common/src/components/CommunityBadges/index.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react'; -import IconBase from 'react-icons/lib/IconBase'; -import Color from 'color'; -import styled from 'styled-components'; -import Tooltip from '../Tooltip'; -import getIcon from '../../templates/icons'; -import getDefinition from '../../templates'; - -const IconContainer = styled.div` - max-width: 30%; - left: 50%; - position: absolute; - top: 6px; - transform: translateX(-50%); - - svg, - img { - max-width: 100%; - filter: grayscale(0.4); - height: auto; - } -`; - -export default ({ style, sandboxesNumber, template }) => { - const templateInfo = getDefinition(template); - const color = templateInfo.color(); - const lighter = Color(color) - .lighten(0.2) - .rgb(); - - const Icon = getIcon(template); - - return sandboxesNumber >= 50 ? ( - - - - - - - - - - - - ) : null; -}; From fd08ad7401982ea4bdf73659481b633511a8d835 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Thu, 16 Jul 2020 15:11:06 +0200 Subject: [PATCH 3/5] delere unsuded components --- .../components/HeaderSearchBar/elements.ts | 4 +- .../IntegrationModal/IntegrationModal.tsx | 9 +- .../pages/Patron/PricingModal/Badge/index.tsx | 9 +- .../PricingModal/PricingChoice/index.tsx | 9 +- .../src/app/pages/common/UserMenu/index.tsx | 9 +- packages/common/src/components/Footer.tsx | 156 ------------- packages/common/src/components/Link.tsx | 30 --- .../common/src/components/Modal/Modal.tsx | 68 ------ .../common/src/components/Modal/elements.ts | 20 -- packages/common/src/components/Modal/index.ts | 1 - .../components/MultiAction/MultiAction.tsx | 94 -------- .../src/components/MultiAction/elements.ts | 104 --------- .../src/components/MultiAction/index.ts | 1 - .../__snapshots__/index.test.tsx.snap | 3 - .../components/Navigation/index.stories.tsx | 7 - .../src/components/Navigation/index.test.tsx | 11 - .../src/components/Navigation/index.tsx | 219 ------------------ .../src/components/Pagination/Pagination.tsx | 123 ---------- .../src/components/Pagination/elements.ts | 49 ---- .../common/src/components/Pagination/index.ts | 1 - .../__snapshots__/index.test.tsx.snap | 7 - .../src/components/ProgressButton/elements.ts | 49 ---- .../ProgressButton/index.stories.tsx | 14 -- .../components/ProgressButton/index.test.tsx | 23 -- .../src/components/ProgressButton/index.tsx | 19 -- .../common/src/components/Switch/elements.ts | 65 ------ .../src/components/Switch/index.stories.tsx | 32 --- .../common/src/components/Switch/index.tsx | 39 ---- .../components/Template/OfficialTemplate.tsx | 43 ---- .../src/components/Template/UserTemplate.tsx | 64 ----- .../src/components/Template/elements.ts | 75 ------ .../common/src/components/Template/index.tsx | 17 -- 32 files changed, 26 insertions(+), 1348 deletions(-) delete mode 100644 packages/common/src/components/Footer.tsx delete mode 100644 packages/common/src/components/Link.tsx delete mode 100644 packages/common/src/components/Modal/Modal.tsx delete mode 100644 packages/common/src/components/Modal/elements.ts delete mode 100644 packages/common/src/components/Modal/index.ts delete mode 100644 packages/common/src/components/MultiAction/MultiAction.tsx delete mode 100644 packages/common/src/components/MultiAction/elements.ts delete mode 100644 packages/common/src/components/MultiAction/index.ts delete mode 100644 packages/common/src/components/Navigation/__snapshots__/index.test.tsx.snap delete mode 100644 packages/common/src/components/Navigation/index.stories.tsx delete mode 100644 packages/common/src/components/Navigation/index.test.tsx delete mode 100644 packages/common/src/components/Navigation/index.tsx delete mode 100644 packages/common/src/components/Pagination/Pagination.tsx delete mode 100644 packages/common/src/components/Pagination/elements.ts delete mode 100644 packages/common/src/components/Pagination/index.ts delete mode 100644 packages/common/src/components/ProgressButton/__snapshots__/index.test.tsx.snap delete mode 100644 packages/common/src/components/ProgressButton/elements.ts delete mode 100644 packages/common/src/components/ProgressButton/index.stories.tsx delete mode 100644 packages/common/src/components/ProgressButton/index.test.tsx delete mode 100644 packages/common/src/components/ProgressButton/index.tsx delete mode 100644 packages/common/src/components/Switch/elements.ts delete mode 100644 packages/common/src/components/Switch/index.stories.tsx delete mode 100644 packages/common/src/components/Switch/index.tsx delete mode 100644 packages/common/src/components/Template/OfficialTemplate.tsx delete mode 100644 packages/common/src/components/Template/UserTemplate.tsx delete mode 100644 packages/common/src/components/Template/elements.ts delete mode 100644 packages/common/src/components/Template/index.tsx diff --git a/packages/app/src/app/components/HeaderSearchBar/elements.ts b/packages/app/src/app/components/HeaderSearchBar/elements.ts index f61b7bf7370..f736538ea25 100644 --- a/packages/app/src/app/components/HeaderSearchBar/elements.ts +++ b/packages/app/src/app/components/HeaderSearchBar/elements.ts @@ -1,8 +1,8 @@ import styled, { css } from 'styled-components'; import BaseSearchIcon from 'react-icons/lib/go/search'; -import Relative from '@codesandbox/common/lib/components/Relative'; -export const Container = styled(Relative)` +export const Container = styled.div` + position: relative; display: flex; align-items: center; font-weight: 500; diff --git a/packages/app/src/app/components/IntegrationModal/IntegrationModal.tsx b/packages/app/src/app/components/IntegrationModal/IntegrationModal.tsx index ac2b390410a..001c3abc45f 100644 --- a/packages/app/src/app/components/IntegrationModal/IntegrationModal.tsx +++ b/packages/app/src/app/components/IntegrationModal/IntegrationModal.tsx @@ -1,7 +1,6 @@ import React from 'react'; import Centered from '@codesandbox/common/lib/components/flex/Centered'; import Margin from '@codesandbox/common/lib/components/spacing/Margin'; -import Relative from '@codesandbox/common/lib/components/Relative'; import { Container, Title, @@ -39,12 +38,16 @@ export const IntegrationModal: React.FC = ({ - +
{!signedIn && ( Sign in to {name} to continue )} {children} - +
); diff --git a/packages/app/src/app/pages/Patron/PricingModal/Badge/index.tsx b/packages/app/src/app/pages/Patron/PricingModal/Badge/index.tsx index e6d016c53e4..511fb719df7 100644 --- a/packages/app/src/app/pages/Patron/PricingModal/Badge/index.tsx +++ b/packages/app/src/app/pages/Patron/PricingModal/Badge/index.tsx @@ -1,6 +1,5 @@ import React, { memo } from 'react'; import { PatronBadge } from '@codesandbox/common/lib/types'; -import Relative from '@codesandbox/common/lib/components/Relative'; import badges from '@codesandbox/common/lib/utils/badges/patron-info'; import './animations.css'; import { Particles } from './Particles'; @@ -16,7 +15,11 @@ export const Badge: React.FC = memo(({ badge, subscribed }) => { const BadgeComponent = badges[badge].Badge; return ( - +
{/* We prerender all particles, performance reasons */} @@ -27,6 +30,6 @@ export const Badge: React.FC = memo(({ badge, subscribed }) => { alt={badge} /> - +
); }); diff --git a/packages/app/src/app/pages/Patron/PricingModal/PricingChoice/index.tsx b/packages/app/src/app/pages/Patron/PricingModal/PricingChoice/index.tsx index f6f1855e8de..0cd3c6ed389 100644 --- a/packages/app/src/app/pages/Patron/PricingModal/PricingChoice/index.tsx +++ b/packages/app/src/app/pages/Patron/PricingModal/PricingChoice/index.tsx @@ -2,7 +2,6 @@ import React, { FunctionComponent } from 'react'; import { format } from 'date-fns'; import { PatronBadge } from '@codesandbox/common/lib/types'; import Centered from '@codesandbox/common/lib/components/flex/Centered'; -import Relative from '@codesandbox/common/lib/components/Relative'; import badges from '@codesandbox/common/lib/utils/badges/patron-info'; import { useOvermind } from 'app/overmind'; import { SubscribeForm } from 'app/components/SubscribeForm'; @@ -44,7 +43,11 @@ export const PricingChoice: FunctionComponent = ({ badge }) => { /> )} - +
$ priceChanged({ price: Number(e.target.value) })} @@ -53,7 +56,7 @@ export const PricingChoice: FunctionComponent = ({ badge }) => { type="number" /> /month - +
{ return ( - +
{ } showBecomePro={!user.subscription} /> - +
); }; diff --git a/packages/common/src/components/Footer.tsx b/packages/common/src/components/Footer.tsx deleted file mode 100644 index afd48f52354..00000000000 --- a/packages/common/src/components/Footer.tsx +++ /dev/null @@ -1,156 +0,0 @@ -import React from 'react'; -import styled from 'styled-components'; -import MaxWidth from './flex/MaxWidth'; - -import media from '../utils/media'; - -const Container = styled.div` - display: flex; - justify-content: space-around; - width: 100%; - padding-top: 5rem; - padding-bottom: 3rem; - flex-wrap: wrap; -`; - -const Column = styled.div` - width: calc(33% - 2rem); - margin: 0 1rem; - - ${media.phone` - width: 100%; - margin-bottom: 1rem; - `}; -`; - -const Title = styled.h5` - font-size: 1.125rem; - font-weight: 400; - margin: 0; - margin-bottom: 1rem; - - color: ${({ theme }) => theme.secondary}; -`; - -const List = styled.ul` - color: rgba(255, 255, 255, 0.7); - list-style-type: none; - margin: 0; - padding: 0; - - li { - a { - transition: 0.3s ease color; - text-decoration: none; - color: rgba(255, 255, 255, 0.7); - - &:hover { - color: rgba(255, 255, 255, 0.9); - } - } - } -`; - -const Background = styled.div` - position: relative; - background-color: ${props => props.theme.background2.darken(0.2)}; - padding: 1rem; - z-index: 5; -`; - -export default () => ( - - - <> - - - CodeSandbox - -
  • - - Create Sandbox - -
  • -
  • - - Search - -
  • -
  • - - Explore - -
  • -
  • - Documentation -
  • -
  • - - Patron - -
  • -
  • - - Status - -
  • -
  • - - Sign In - -
  • -
    -
    - - - About - -
  • - - Blog - -
  • -
  • - - GitHub - -
  • -
  • - Careers -
  • -
  • - Legal -
  • -
  • - Contact Us -
  • -
    -
    - - - Social - -
  • - - Twitter - -
  • -
    -
    -
    - -
    -
    -); diff --git a/packages/common/src/components/Link.tsx b/packages/common/src/components/Link.tsx deleted file mode 100644 index 58d21e87a7a..00000000000 --- a/packages/common/src/components/Link.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; -import { Link as RouterLink } from 'react-router-dom'; - -export interface ILinkProps { - to?: any; - external?: boolean; - onClick?: React.MouseEventHandler; -} - -export const Link: React.FC = React.forwardRef< - HTMLAnchorElement, - ILinkProps ->(({ to = undefined, external = false, onClick, children, ...props }, ref) => - external ? ( - - {children} - - ) : ( - - {children} - - ) -); diff --git a/packages/common/src/components/Modal/Modal.tsx b/packages/common/src/components/Modal/Modal.tsx deleted file mode 100644 index 883d09f2298..00000000000 --- a/packages/common/src/components/Modal/Modal.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React, { ComponentProps } from 'react'; -import { - useDialogState, - DialogDisclosure, - DialogBackdrop, - Dialog, -} from 'reakit/Dialog'; -import { Portal } from 'reakit/Portal'; -import { Button } from '../Button'; -import { Backdrop, Container } from './elements'; - -export interface IModalProps extends ComponentProps { - label?: string; - button?: React.ElementType; - backdrop?: React.ElementType; - container?: React.ElementType; - isOpen?: boolean; - onClose?: () => void; - children: - | (({ open: boolean, toggleOpen: Function }) => React.ReactNode) - | React.ReactNode; -} - -export const Modal: React.FC = ({ - label, - button = Button, - backdrop = Backdrop, - container = Container, - isOpen, - onClose = () => undefined, - children, - ...props -}) => { - const dialog = useDialogState(); - const onHide = () => { - dialog.hide(); - onClose(); - }; - - return ( - <> - {label && ( - - {label} - - )} - - - - {typeof children === `function` - ? (children as Function)({ - open: dialog.visible, - toggleOpen: dialog.toggle, - }) - : children} - - - - - ); -}; diff --git a/packages/common/src/components/Modal/elements.ts b/packages/common/src/components/Modal/elements.ts deleted file mode 100644 index 920707da465..00000000000 --- a/packages/common/src/components/Modal/elements.ts +++ /dev/null @@ -1,20 +0,0 @@ -import styled from 'styled-components'; - -export const Backdrop = styled.div` - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 999; - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 100vh; - background-color: rgba(0, 0, 0, 0.5); -`; - -export const Container = styled.div` - margin: 2rem; -`; diff --git a/packages/common/src/components/Modal/index.ts b/packages/common/src/components/Modal/index.ts deleted file mode 100644 index ea3b791a0b2..00000000000 --- a/packages/common/src/components/Modal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Modal, IModalProps } from './Modal'; diff --git a/packages/common/src/components/MultiAction/MultiAction.tsx b/packages/common/src/components/MultiAction/MultiAction.tsx deleted file mode 100644 index 2490ec37376..00000000000 --- a/packages/common/src/components/MultiAction/MultiAction.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import React, { memo, cloneElement, Children } from 'react'; -import GoChevronDown from 'react-icons/lib/go/chevron-down'; -import GoChevronUp from 'react-icons/lib/go/chevron-up'; -import { useMenuState, MenuStateReturn } from 'reakit/Menu'; -import { - Container, - PrimaryAction, - ToggleActionsList, - ActionsList, - SecondaryAction, -} from './elements'; - -interface IMultiActionProps { - Icon?: any; - primaryActionLabel: string; - onPrimaryClick?: (event: React.MouseEvent, menu: MenuStateReturn) => void; - disablePrimary?: boolean; - small?: boolean; - block?: boolean; - disabled?: boolean; - light?: boolean; - secondary?: boolean; - red?: boolean; - danger?: boolean; - className?: string; - children: React.ReactElement | React.ReactElement[]; -} - -export const MultiAction: React.FC = memo( - ({ - Icon, - primaryActionLabel, - onPrimaryClick, - disablePrimary = false, - small = false, - block = false, - disabled = false, - secondary = false, - red = false, - danger = false, - children, - className, - }) => { - const menu = useMenuState(); - const buttonProps = { small, block, disabled, secondary, red, danger }; - - return ( - - {/* - // @ts-ignore */} - onPrimaryClick(e, menu)} - className={className} - {...buttonProps} - disabled={disablePrimary || disabled} - > - {Icon && } - {primaryActionLabel} - - - {menu.visible ? : } - - - {children && (children as React.ReactElement[]).length - ? /* eslint-disable react/no-array-index-key */ - (children as React.ReactElement[]).map((child, i) => ( - { - if (child.props.onClick) { - child.props.onClick(e, menu); - } - }} - > - {itemProps => cloneElement(Children.only(child), itemProps)} - - )) - : !Array.isArray(children) && ( - - {itemProps => - cloneElement(Children.only(children), itemProps) - } - - )} - - - ); - } -); diff --git a/packages/common/src/components/MultiAction/elements.ts b/packages/common/src/components/MultiAction/elements.ts deleted file mode 100644 index d409dd4706b..00000000000 --- a/packages/common/src/components/MultiAction/elements.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { ComponentProps } from 'react'; -import { Button as ReakitButton } from 'reakit/Button'; -import { Group } from 'reakit/Group'; -import { Menu, MenuItem, MenuDisclosure } from 'reakit/Menu'; -import styled, { css } from 'styled-components'; - -import { Button, buttonStyles } from '../Button'; - -export const Container = styled(Group)` - position: relative; - display: flex; -`; - -export const PrimaryAction = styled(ReakitButton)< - ComponentProps ->` - ${({ block }) => css` - ${buttonStyles}; - justify-content: center; - width: ${block ? '100%' : 'inherit'}; - border-radius: 0; - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - border-right-width: 1px; - `} -`; - -export const ToggleActionsList = styled(MenuDisclosure)< - ComponentProps ->` - ${buttonStyles}; - justify-content: center; - width: 32px; - height: 32px; - border-radius: 0; - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - border-left-width: 1px; - - &:focus { - outline: 0 !important; - } -`; - -export const ActionsList = styled(Menu).attrs({ - modal: false, - style: { - zIndex: 1, - top: '32px', - left: 'inherit', - right: '0px', - transform: 'none', - }, -})` - display: flex; - flex-direction: column; - width: max-content; - min-width: 100%; - margin-top: -2px; - border-radius: 2px; - background-color: ${props => - props.theme['menu.background'] || props.theme.background4}; - box-shadow: rgba(0, 0, 0, 0.75) 0px 3px 8px; - - &:focus { - outline: none !important; - } -`; - -export const SecondaryAction = styled(MenuItem)<{ disabled?: boolean }>` - ${({ disabled, theme }) => css` - display: inline-flex; - padding: 0.5rem 1rem; - border: none; - background: none; - color: ${theme['menu.foreground'] || 'rgba(255, 255, 255, 0.8)'}; - text-align: initial; - ${!disabled && - css` - cursor: pointer; - `}; - - &:focus { - outline: none !important; - } - - &:focus { - border-color: rgb(64, 169, 243); - background-color: ${theme['menu.selectionBackground'] || - theme.background3}; - color: ${theme['menu.selectionForeground'] || 'white'}; - } - - &:first-child { - border-top-left-radius: 4px; - border-top-right-radius: 4px; - } - - &:last-child { - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - } - `} -`; diff --git a/packages/common/src/components/MultiAction/index.ts b/packages/common/src/components/MultiAction/index.ts deleted file mode 100644 index 35539de2f87..00000000000 --- a/packages/common/src/components/MultiAction/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { MultiAction } from './MultiAction'; diff --git a/packages/common/src/components/Navigation/__snapshots__/index.test.tsx.snap b/packages/common/src/components/Navigation/__snapshots__/index.test.tsx.snap deleted file mode 100644 index 8358202c0d2..00000000000 --- a/packages/common/src/components/Navigation/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` rendering basic 1`] = `ReactWrapper {}`; diff --git a/packages/common/src/components/Navigation/index.stories.tsx b/packages/common/src/components/Navigation/index.stories.tsx deleted file mode 100644 index 0ad6c6f54ca..00000000000 --- a/packages/common/src/components/Navigation/index.stories.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; -import { storiesOf } from '@storybook/react'; -import Navigation from '.'; - -const stories = storiesOf('components/Navigation', module); - -stories.add('Navigation', () => ); diff --git a/packages/common/src/components/Navigation/index.test.tsx b/packages/common/src/components/Navigation/index.test.tsx deleted file mode 100644 index 4a518e21f9f..00000000000 --- a/packages/common/src/components/Navigation/index.test.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import 'jest-styled-components'; -import React from 'react'; -import mountWithTheme from '../../test/themeMount'; -import Navigation from '.'; - -describe(' rendering', () => { - it('basic', () => { - const wrapper = mountWithTheme(); - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/packages/common/src/components/Navigation/index.tsx b/packages/common/src/components/Navigation/index.tsx deleted file mode 100644 index e973f6ce48f..00000000000 --- a/packages/common/src/components/Navigation/index.tsx +++ /dev/null @@ -1,219 +0,0 @@ -import React from 'react'; -import styled, { css } from 'styled-components'; - -import Logo from '../Logo'; -import MaxWidth from '../flex/MaxWidth'; - -import media from '../../utils/media'; -import track from '../../utils/analytics'; - -const Container = styled.div` - display: flex; - align-items: center; - padding: 1rem 0; - width: 100%; - color: white; - z-index: 5; -`; - -const Left = styled.div` - display: flex; - align-items: center; - flex: auto; -`; - -const StyledLogo = styled(Logo)` - color: white; - ${media.phone` - width: 38px; - height: 38px; - `}; -`; - -const Item = styled.a<{ - button?: boolean; - hidePhone?: boolean; - hideOn?: number; -}>` - display: inline-flex; - align-items: center; - transition: 0.2s ease color; - font-size: 1.125rem; - text-decoration: none; - color: white; - - margin: 0 1rem; - font-weight: 400; - - &:hover { - color: ${props => props.theme.secondary}; - } - - ${props => - props.button && - css` - transition: 0.3s ease all; - padding: 0.2rem 0.8rem; - border-radius: 4px; - font-weight: 600; - background-color: ${props.theme.secondary}; - border: 2px solid rgba(255, 255, 255, 0.3); - - &:hover { - color: white; - background-color: #7fc3f7; - border-color: transparent; - } - `}; - - ${media.phone` - font-size: 1rem; - margin: 0 .5rem; - `}; - - ${props => - props.hidePhone && - css` - ${media.phone` - display: none; - `}; - `}; - - ${props => - props.hideOn && - css` - @media (max-width: ${props.hideOn}px) { - display: none; - } - `}; -`; - -const Right = styled.div` - display: flex; - align-items: center; -`; - -const Image = styled.img` - width: 1.75em; - height: 1.75em; - border-radius: 4px; - margin-left: 0.75rem; - margin-bottom: 0; -`; - -const Ul = styled.ul` - list-style: none; - margin: 0; - display: flex; - align-items: center; - flex: auto; -`; - -const Li = styled.li` - margin: 0; -`; - -export default class Navigation extends React.PureComponent { - state = { - user: null, - }; - - fetchCurrentUser = () => { - const BASE = - process.env.NODE_ENV === 'development' ? 'http://localhost:3000' : ''; - - window - .fetch(BASE + '/api/v1/users/current') - .then(x => x.json()) - .then(({ data }) => this.setState({ user: data })) - .catch(() => { - /* do nothing */ - }); - }; - - componentDidMount() { - if (document.cookie.indexOf('signedIn') > -1) { - this.fetchCurrentUser(); - } - } - - render() { - const { user } = this.state; - return ( - - - - - - - -
      -
    • - Explore -
    • -
    • - Search -
    • -
    • - Docs -
    • -
    • - Blog -
    • -
    • - - GitHub - -
    • -
    • - Careers -
    • -
    -
    - - -
      - {!user && ( -
    • - - Sign In - -
    • - )} -
    • - { - track('Navigation - Create Sandbox Clicked'); - }} - hidePhone - href="/s" - rel="noopener noreferrer" - button={!user} - > - Create Sandbox - -
    • - {user && ( -
    • - - {user.username} - {user.username} - -
    • - )} -
    -
    -
    -
    - ); - } -} diff --git a/packages/common/src/components/Pagination/Pagination.tsx b/packages/common/src/components/Pagination/Pagination.tsx deleted file mode 100644 index e7a077f3571..00000000000 --- a/packages/common/src/components/Pagination/Pagination.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import React, { useState } from 'react'; -import MdFirstPage from 'react-icons/lib/md/first-page'; -import MdChevronLeft from 'react-icons/lib/md/chevron-left'; -import MdChevronRight from 'react-icons/lib/md/chevron-right'; -import MdLastPage from 'react-icons/lib/md/last-page'; -import { clamp, range } from '../../utils'; -import { Navigation, Controls, Button as DefaultButton } from './elements'; - -type NavButton = React.FC<{ - disabled?: boolean; - onClick: () => void; -}>; - -interface IPaginationProps { - onChange?: (currentPage: number) => void; - neighbors?: number; - pages?: number; - initial?: number; - Button?: React.ReactType; - First?: NavButton; - Previous?: NavButton; - Next?: NavButton; - Last?: NavButton; -} - -export const Pagination: React.FC = ({ - onChange = () => {}, - neighbors = 2, - pages = 1, - initial = 1, - Button = DefaultButton, - First = props => ( -
  • - -
  • - ), - Previous = props => ( -
  • - -
  • - ), - Next = props => ( -
  • - -
  • - ), - Last = props => ( -
  • - -
  • - ), - ...props -}) => { - const [currentPage, setCurrentPage] = useState(initial); - - const fetchPageNumbers = () => { - if (pages <= 0) { - return []; - } - - const middle = clamp(currentPage, neighbors + 1, pages - neighbors); - const start = Math.max(1, middle - neighbors); - const end = Math.min(pages, middle + neighbors); - - return range(end - start + 1, start); - }; - - const gotoPage = (page: number) => { - const destination = Math.max(0, Math.min(page, pages)); - setCurrentPage(destination); - onChange(destination); - }; - - const handleClick = (page: number) => () => { - gotoPage(page); - }; - - const handleFirst = () => { - gotoPage(1); - }; - - const handlePrevious = () => { - gotoPage(currentPage - 1); - }; - - const handleNext = () => { - gotoPage(currentPage + 1); - }; - - const handleLast = () => { - gotoPage(pages); - }; - - return ( - - - - - {fetchPageNumbers().map((page: number) => ( -
  • - -
  • - ))} - - -
    -
    - ); -}; diff --git a/packages/common/src/components/Pagination/elements.ts b/packages/common/src/components/Pagination/elements.ts deleted file mode 100644 index 5dd270ef47d..00000000000 --- a/packages/common/src/components/Pagination/elements.ts +++ /dev/null @@ -1,49 +0,0 @@ -import styled, { css } from 'styled-components'; -import { Button as BaseButton } from 'reakit/Button'; -import { withoutProps } from '../../utils'; - -export const Navigation = styled.nav.attrs({ - role: 'navigation', - 'aria-label': 'Pagination Navigation', -})``; - -export const Controls = styled.ul` - display: flex; - list-style: none; - margin: 0; - padding: 0; -`; - -export const Button = styled(withoutProps(`active`)(BaseButton))<{ - active: boolean; -}>` - ${({ active }) => css` - display: inline-flex; - justify-content: center; - align-items: center; - width: 34px; - height: 22px; - padding: 0; - margin: 0 2px; - border: none; - background: ${active ? css`#40A9F3` : css`none`}; - border-radius: 4px; - color: ${active ? css`#fff` : css`#b8b9ba`}; - font-family: Roboto; - font-style: normal; - font-weight: bold; - font-size: 14px; - cursor: pointer; - - &:disabled { - color: ${active ? css`#fff` : css`#666`}; - cursor: default; - } - - &:hover:not(:disabled), - &:focus:not(:disabled) { - color: #fff; - background: ${active ? css`#40A9F3` : css`rgba(108, 174, 221, 0.2);`}; - } - `} -`; diff --git a/packages/common/src/components/Pagination/index.ts b/packages/common/src/components/Pagination/index.ts deleted file mode 100644 index 0a1fd4dad6c..00000000000 --- a/packages/common/src/components/Pagination/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Pagination } from './Pagination'; diff --git a/packages/common/src/components/ProgressButton/__snapshots__/index.test.tsx.snap b/packages/common/src/components/ProgressButton/__snapshots__/index.test.tsx.snap deleted file mode 100644 index aec33650d28..00000000000 --- a/packages/common/src/components/ProgressButton/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` rendering basic 1`] = `ReactWrapper {}`; - -exports[` rendering disabled 1`] = `ReactWrapper {}`; - -exports[` rendering loading 1`] = `ReactWrapper {}`; diff --git a/packages/common/src/components/ProgressButton/elements.ts b/packages/common/src/components/ProgressButton/elements.ts deleted file mode 100644 index c3048cf0b1d..00000000000 --- a/packages/common/src/components/ProgressButton/elements.ts +++ /dev/null @@ -1,49 +0,0 @@ -import styled, { css, keyframes } from 'styled-components'; -import { Button } from '../Button'; -import theme from '../../theme'; - -const loaderAnimation = keyframes` - 0% { background-color: ${theme.secondary()}; } - 50%, 100% { background-color: ${theme.secondary.lighten(0.5)()}; } -`; - -export const Wrapper = styled.div` - position: relative; -`; - -export const RelativeButton = styled(Button)` - position: relative; -`; - -const circle = css` - width: 8px; - height: 8px; - border-radius: 50%; - background: ${theme.secondary()}; - opacity: 0.7; - animation: ${loaderAnimation} 1s infinite linear alternate; -`; - -export const Loader = styled.div` - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - ${circle} animation-delay: 0.5s; - - &:before { - content: ' '; - position: absolute; - left: -12px; - ${circle}; - animation-delay: 0s; - } - - &:after { - content: ' '; - position: absolute; - left: 12px; - ${circle}; - animation-delay: 1s; - } -`; diff --git a/packages/common/src/components/ProgressButton/index.stories.tsx b/packages/common/src/components/ProgressButton/index.stories.tsx deleted file mode 100644 index 3315cb00c7c..00000000000 --- a/packages/common/src/components/ProgressButton/index.stories.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import { storiesOf } from '@storybook/react'; -import ProgressButton from '.'; - -const stories = storiesOf('components/ProgressButton', module); - -stories - .add('Basic ProgressButton', () => Click Me) - .add('ProgressButton disabled', () => ( - Click Me - )) - .add('ProgressButton loading', () => ( - Click Me - )); diff --git a/packages/common/src/components/ProgressButton/index.test.tsx b/packages/common/src/components/ProgressButton/index.test.tsx deleted file mode 100644 index a012bb05e4e..00000000000 --- a/packages/common/src/components/ProgressButton/index.test.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import 'jest-styled-components'; -import React from 'react'; -import mountWithTheme from '../../test/themeMount'; -import ProgressButton from '.'; - -describe(' rendering', () => { - it('basic', () => { - const wrapper = mountWithTheme(Click Me); - expect(wrapper).toMatchSnapshot(); - }); - it('disabled', () => { - const wrapper = mountWithTheme( - Click Me - ); - expect(wrapper).toMatchSnapshot(); - }); - it('loading', () => { - const wrapper = mountWithTheme( - Click Me - ); - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/packages/common/src/components/ProgressButton/index.tsx b/packages/common/src/components/ProgressButton/index.tsx deleted file mode 100644 index 345f70a4fc8..00000000000 --- a/packages/common/src/components/ProgressButton/index.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React, { ComponentProps, FunctionComponent } from 'react'; -import { Button } from '../Button'; -import { Wrapper, Loader } from './elements'; - -type Props = ComponentProps & { - loading?: boolean; -}; -const ProgressButton: FunctionComponent = ({ - disabled = false, - loading = false, - ...props -}) => ( - - - ); -}; diff --git a/packages/common/src/components/Template/UserTemplate.tsx b/packages/common/src/components/Template/UserTemplate.tsx deleted file mode 100644 index 1add43e7f05..00000000000 --- a/packages/common/src/components/Template/UserTemplate.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React from 'react'; -import { ColorIcons as Icons } from 'template-icons'; -import { Template } from '../../types/index'; -import getIcon from '../../templates/icons'; -import { ENTER } from '../../utils/keycodes'; -import { Button, IconContainer, Title } from './elements'; -import { TemplateType } from '../../templates'; -import { getSandboxName } from '../../utils/get-sandbox-name'; - -interface UserTemplate extends Template { - iconUrl?: string; - id?: string; - title?: string; - sandbox?: { - alias: string; - id: string; - title: string; - source: { - template: TemplateType; - }; - }; -} - -interface IUserTemplateProps { - template: UserTemplate; - selectTemplate: (t: Template) => void; - small: boolean; -} - -export const UserTemplate = ({ - template, - selectTemplate, - small, -}: IUserTemplateProps) => { - const Icon = - template.iconUrl && Icons[template.iconUrl] - ? Icons[template.iconUrl] - : getIcon(template.sandbox.source.template); - - const select = () => - selectTemplate({ - ...template, - shortid: template.sandbox.alias || template.sandbox.id, - }); - - return ( - - ); -}; diff --git a/packages/common/src/components/Template/elements.ts b/packages/common/src/components/Template/elements.ts deleted file mode 100644 index 4587c8e90ef..00000000000 --- a/packages/common/src/components/Template/elements.ts +++ /dev/null @@ -1,75 +0,0 @@ -import styled, { css } from 'styled-components'; -import Color from 'color'; - -const makeColor = ( - color: any, - custom: boolean, - checkContrast: boolean, - theme?: any -): string => { - if (!custom) { - return color; - } - - if (checkContrast && theme) { - return color.contrast(Color('#fff')) < 6.5 - ? color.rgbString() - : theme.gray(); - } - - return color.rgbString(); -}; - -export const Button = styled.button<{ - selected?: boolean; - color: any; - custom?: boolean; -}>` - ${({ color, selected, custom, theme }) => css` - display: flex; - align-items: center; - padding: 1em; - border: 2px solid rgba(0, 0, 0, 0.3); - border-radius: 4px; - background-color: rgba(0, 0, 0, 0.2); - color: ${makeColor(color, custom, true, theme)}; - text-align: left; - transition: 0.3s ease all; - cursor: pointer; - outline: none; - - ${selected - ? css` - border-color: rgba(255, 255, 255, 0.2); - background-color: ${makeColor(color.clearer(0.3), custom, false)}; - color: ${makeColor(color, custom, true, theme)}; - ` - : css` - &:hover, - &:focus { - border-color: rgba(255, 255, 255, 0.1); - color: white; - background-color: ${makeColor(color.clearer(0.6), custom, false)}; - } - `}; - `} -`; - -export const Title = styled.div` - display: -webkit-box; - max-height: 32px; /* fallback */ - font-family: Poppins, Roboto, sans-serif; - font-size: 0.875rem; - font-weight: 500; - line-height: 16px; /* fallback */ - overflow: hidden; - text-overflow: ellipsis; - -webkit-line-clamp: 2; /* number of lines to show */ - -webkit-box-orient: vertical; -`; - -export const IconContainer = styled.div` - display: flex; - align-items: center; - margin-right: 0.75em; -`; diff --git a/packages/common/src/components/Template/index.tsx b/packages/common/src/components/Template/index.tsx deleted file mode 100644 index 251fd2712f6..00000000000 --- a/packages/common/src/components/Template/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import { Template } from '../../types/index'; -import { OfficialTemplate } from './OfficialTemplate'; -import { UserTemplate } from './UserTemplate'; - -interface ITemplateProps { - template: Template; - selectTemplate: (t: Template) => void; - small: boolean; -} - -export default (props: ITemplateProps) => - props.template.niceName ? ( - - ) : ( - - ); From 6fd76db288d29cb47bd0314bb8c8ff8573be8e56 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Thu, 30 Jul 2020 15:55:10 +0200 Subject: [PATCH 4/5] add redirects --- packages/app/src/app/pages/Dashboard/Content/index.tsx | 8 +++++++- packages/app/src/app/pages/index.tsx | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/app/src/app/pages/Dashboard/Content/index.tsx b/packages/app/src/app/pages/Dashboard/Content/index.tsx index 9e46b95817f..8e21983b0af 100644 --- a/packages/app/src/app/pages/Dashboard/Content/index.tsx +++ b/packages/app/src/app/pages/Dashboard/Content/index.tsx @@ -13,6 +13,7 @@ import { All } from './routes/All'; import { Repositories } from './routes/Repositories'; import { Search } from './routes/Search'; import { Settings } from './routes/Settings'; +import { NewTeam } from './routes/Settings/NewTeam'; export const Content = withRouter(({ history }) => { const { actions, state } = useOvermind(); @@ -43,14 +44,19 @@ export const Content = withRouter(({ history }) => { + // old dashboard redirect + + // old dashboard redirect + - + // old dashboard redirect + diff --git a/packages/app/src/app/pages/index.tsx b/packages/app/src/app/pages/index.tsx index 8886bb87b81..b960d6d0b6d 100644 --- a/packages/app/src/app/pages/index.tsx +++ b/packages/app/src/app/pages/index.tsx @@ -146,6 +146,7 @@ const RoutesComponent: React.FC = () => { component={() => } /> + From bfe50e0e7fb0ea295fc62b54b212b049a0fac634 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Thu, 30 Jul 2020 18:12:55 +0200 Subject: [PATCH 5/5] fix ts --- .../src/app/pages/Dashboard/Sidebar/index.tsx | 75 +- .../app/pages/NewDashboard/Sidebar/index.tsx | 714 ------------------ 2 files changed, 58 insertions(+), 731 deletions(-) delete mode 100644 packages/app/src/app/pages/NewDashboard/Sidebar/index.tsx diff --git a/packages/app/src/app/pages/Dashboard/Sidebar/index.tsx b/packages/app/src/app/pages/Dashboard/Sidebar/index.tsx index 533ce445c98..c2265f45765 100644 --- a/packages/app/src/app/pages/Dashboard/Sidebar/index.tsx +++ b/packages/app/src/app/pages/Dashboard/Sidebar/index.tsx @@ -24,11 +24,11 @@ import { } from '@codesandbox/components'; import css from '@styled-system/css'; import merge from 'deepmerge'; +import { WorkspaceSelect } from 'app/components/WorkspaceSelect'; import { ContextMenu } from './ContextMenu'; import { DashboardBaseFolder, PageTypes } from '../types'; import { Position } from '../Components/Selection'; import { SIDEBAR_WIDTH } from './constants'; -import { WorkspaceSwitcher } from './WorkspaceSwitcher'; import { DragItemType, useDrop } from '../utils/dnd'; const SidebarContext = React.createContext(null); @@ -47,13 +47,21 @@ export const Sidebar: React.FC = ({ ...props }) => { const { state, actions } = useOvermind(); - const [activeAccount, setActiveAccount] = useState<{ - username: string | null; - avatarUrl: string | null; - }>({ - username: null, - avatarUrl: null, - }); + const [activeAccount, setActiveAccount] = useState< + | { + type: 'user'; + id: string; + username: string; + avatarUrl: string; + } + | { + type: 'team'; + id: string; + name: string; + avatarUrl: string; + } + | null + >(null); const { dashboard, user, activeTeam } = state; React.useEffect(() => { @@ -65,18 +73,22 @@ export const Sidebar: React.FC = ({ const team = dashboard.teams.find(({ id }) => id === state.activeTeam); if (team) - setActiveAccount({ username: team.name, avatarUrl: team.avatarUrl }); + setActiveAccount({ + type: 'team', + id: team.id, + name: team.name, + avatarUrl: team.avatarUrl, + }); } else if (user) { setActiveAccount({ + type: 'user', + id: user.id, username: user.username, avatarUrl: user.avatarUrl, }); } }, [state.activeTeam, state.activeTeamInfo, dashboard.teams, user]); - const inTeamContext = - activeAccount && user && activeAccount.username !== user.username; - const folders = dashboard.allCollections || []; // context menu for folders @@ -128,11 +140,40 @@ export const Sidebar: React.FC = ({ })} > - - + + {activeAccount && ( + { + actions.setActiveTeam({ + id: workspace.type === 'user' ? null : workspace.id, + }); + }} + activeAccount={activeAccount} + /> + )} + + + void; - css?: any; - style?: React.CSSProperties; - id?: string; -} - -export const Sidebar: React.FC = ({ - visible, - onSidebarToggle, - ...props -}) => { - const { state, actions } = useOvermind(); - const [activeAccount, setActiveAccount] = useState< - | { - type: 'user'; - id: string; - username: string; - avatarUrl: string; - } - | { - type: 'team'; - id: string; - name: string; - avatarUrl: string; - } - | null - >(null); - const { dashboard, user, activeTeam } = state; - - React.useEffect(() => { - actions.dashboard.getAllFolders(); - }, [actions.dashboard, state.activeTeam]); - - React.useEffect(() => { - if (state.activeTeam) { - const team = dashboard.teams.find(({ id }) => id === state.activeTeam); - - if (team) - setActiveAccount({ - type: 'team', - id: team.id, - name: team.name, - avatarUrl: team.avatarUrl, - }); - } else if (user) { - setActiveAccount({ - type: 'user', - id: user.id, - username: user.username, - avatarUrl: user.avatarUrl, - }); - } - }, [state.activeTeam, state.activeTeamInfo, dashboard.teams, user]); - - const folders = dashboard.allCollections || []; - - // context menu for folders - const [menuVisible, setMenuVisibility] = React.useState(true); - const [menuPosition, setMenuPosition] = React.useState({ - x: null, - y: null, - }); - const [ - menuFolder, - setMenuFolder, - ] = React.useState(null); - const [isRenamingFolder, setRenamingFolder] = React.useState(false); - const [newFolderPath, setNewFolderPath] = React.useState(null); - - const menuState = { - menuFolder, - setMenuFolder, - setMenuVisibility, - menuPosition, - setMenuPosition, - isRenamingFolder, - setRenamingFolder, - newFolderPath, - setNewFolderPath, - }; - - return ( - - - - - {activeAccount && ( - { - actions.setActiveTeam({ - id: workspace.type === 'user' ? null : workspace.id, - }); - }} - activeAccount={activeAccount} - /> - )} - - - - - - - - - - - - - - - - - - - {visible && ( - - )} - - - - ); -}; - -// I hate this! but we need this until I refactor how -// components are structured — Sid -// https://linear.app/issue/CSB-118 -const linkStyles = { - width: '100%', - height: '100%', - display: 'flex', - alignItems: 'center', - paddingLeft: 8, - paddingRight: 8, - flexShrink: 0, -}; - -const canNotAcceptSandboxes: PageTypes[] = ['home', 'recents']; -const canNotAcceptFolders: PageTypes[] = [ - 'home', - 'recents', - 'drafts', - 'templates', -]; - -const isSamePath = ( - draggedItem: DragItemType, - currentPage: PageTypes, - dropPath: string -) => { - if (!draggedItem) return false; - - if ( - draggedItem.type === 'sandbox' && - draggedItem.sandbox.collection?.path === dropPath - ) { - return true; - } - - if (draggedItem.type === 'template' && currentPage === 'templates') { - return true; - } - - if ( - draggedItem.type === 'folder' && - (draggedItem.path === dropPath || draggedItem.parent === dropPath) - ) { - return true; - } - - return false; -}; - -interface RowItemProps { - name: string; - path: string; - icon: IconNames; - page: PageTypes; - setFoldersVisibility?: (val: boolean) => void; - folderPath?: string; - style?: React.CSSProperties; -} - -const RowItem: React.FC = ({ - name, - path, - folderPath = path, - page, - icon, - setFoldersVisibility = null, - ...props -}) => { - const accepts: Array<'sandbox' | 'folder' | 'template'> = []; - if (!canNotAcceptSandboxes.includes(page)) { - accepts.push('template'); - accepts.push('sandbox'); - } - if (!canNotAcceptFolders.includes(page)) accepts.push('folder'); - - const usedPath = folderPath || path; - const [{ canDrop, isOver, isDragging }, dropRef] = useDrop({ - accept: accepts, - drop: item => ({ - page, - path: usedPath, - isSamePath: isSamePath(item, page, usedPath), - }), - collect: monitor => ({ - isOver: monitor.isOver(), - canDrop: - monitor.canDrop() && !isSamePath(monitor.getItem(), page, usedPath), - isDragging: !!monitor.getItem(), - }), - }); - - const { onSidebarToggle } = React.useContext(SidebarContext); - - const linkTo: string = path; - - const location = useLocation(); - const isCurrentLink = linkTo.replace(/\?.*/, '') === location.pathname; - const history = useHistory(); - - /** Toggle nested folders when user - * is drags an item over a folder after a treshold - * We open All Sandboxes instantly because that's the root - * and you can't drop anything in it - */ - const HOVER_THRESHOLD = name === 'All Sandboxes' ? 0 : 500; // ms - const isOverCache = React.useRef(false); - - React.useEffect(() => { - if (!isOver) isOverCache.current = false; - else isOverCache.current = true; - - const handler = () => { - if (isOverCache.current && setFoldersVisibility) { - setFoldersVisibility(true); - } - }; - - const timer = window.setTimeout(handler, HOVER_THRESHOLD); - return () => window.clearTimeout(timer); - }, [isOver, setFoldersVisibility, HOVER_THRESHOLD]); - - return ( - theme.speeds[4], - a: { - ':focus': { - // focus state is handled by ListAction:focus-within - outline: 'none', - }, - }, - }, - props.style || {} - ) - )} - > - {props.children || ( - { - if (event.keyCode === ENTER) { - history.push(linkTo, { focus: 'FIRST_ITEM' }); - } - }} - > - - - - {name} - - )} - - ); -}; - -interface NestableRowItemProps { - name: string; - folderPath: string; - path: string; - folders: DashboardBaseFolder[]; -} - -const NestableRowItem: React.FC = ({ - name, - path, - folderPath, - folders, -}) => { - const { actions, state } = useOvermind(); - - const { - menuState: { - menuFolder, - setMenuFolder, - setMenuVisibility, - setMenuPosition, - isRenamingFolder, - setRenamingFolder, - newFolderPath, - setNewFolderPath, - }, - } = React.useContext(SidebarContext); - - const [foldersVisible, setFoldersVisibility] = React.useState(false); - - let hasNewNestedFolder = false; - if (newFolderPath !== null) { - const newFolderParent = newFolderPath.replace('/__NEW__', ''); - if (name === 'All Sandboxes') { - hasNewNestedFolder = true; - } else if (newFolderParent.length && folderPath.includes(newFolderParent)) { - hasNewNestedFolder = true; - } - } - - const location = useLocation(); - const currentFolderLocationPath = dashboardUrls.allSandboxes(folderPath); - React.useEffect(() => { - // Auto open folder in the sidebar if it's opened - const pathName = location.pathname; - const prefixCheck = - folderPath === '/' - ? currentFolderLocationPath - : currentFolderLocationPath + '/'; - - if (pathName.startsWith(prefixCheck) && !foldersVisible) { - setFoldersVisibility(true); - } - - // We don't want to recalculate after mount - // eslint-disable-next-line - }, [location.pathname, currentFolderLocationPath, setFoldersVisibility]); - - React.useEffect(() => { - if (hasNewNestedFolder) setFoldersVisibility(true); - }, [hasNewNestedFolder]); - - const onContextMenu = event => { - event.preventDefault(); - setMenuVisibility(true); - setMenuFolder({ name, path: folderPath }); - setMenuPosition({ x: event.clientX, y: event.clientY }); - }; - - let subFolders: DashboardBaseFolder[]; - if (name === 'All Sandboxes') { - subFolders = folders.filter(folder => { - if (folder.path === newFolderPath) { - return newFolderPath.replace('/__NEW__', '') === ''; - } - return !folder.parent; - }); - } else { - subFolders = folders.filter(folder => { - const parentPath = folder.path - .split('/') - .slice(0, -1) - .join('/'); - - return parentPath === folderPath; - }); - } - - const nestingLevel = - folderPath === '/' ? 0 : folderPath.split('/').length - 1; - const history = useHistory(); - - /* Rename logic */ - const isRenaming = isRenamingFolder && menuFolder.path === folderPath; - const isNewFolder = newFolderPath === folderPath; - const [newName, setNewName] = React.useState(name); - - const onChange = (event: React.ChangeEvent) => { - setNewName(event.target.value); - }; - const onInputKeyDown = (event: React.KeyboardEvent) => { - if (event.keyCode === ESC) { - // Reset value and exit without saving - setNewName(name); - setRenamingFolder(false); - setNewFolderPath(null); - } - }; - - const onSubmit = async (event?: React.FormEvent) => { - if (event) event.preventDefault(); - - if (name === newName) { - // nothing to do here - } else if (isNewFolder) { - if (newName) { - const sanitizedPath = folderPath.replace('__NEW__', newName); - await actions.dashboard.createFolder(sanitizedPath); - track('Dashboard - Create Directory', { - source: 'Sidebar', - dashboardVersion: 2, - folderPath: sanitizedPath, - }); - } - } else { - const newPath = join(dirname(folderPath), newName); - await actions.dashboard.renameFolder({ - path: folderPath, - newPath, - teamId: state.activeTeam, - newTeamId: state.activeTeam, - }); - - track('Dashboard - Rename Folder', { - source: 'Sidebar', - dashboardVersion: 2, - }); - - if (currentFolderLocationPath === location.pathname) { - // if this directory is opened - history.push(dashboardUrls.allSandboxes(newPath, state.activeTeam)); - } - } - - setNewFolderPath(null); - return setRenamingFolder(false); - }; - - const onInputBlur = () => { - // save value when you click outside or tab away - setRenamingFolder(false); - setNewFolderPath(null); - onSubmit(); - }; - - const folderUrl = dashboardUrls.allSandboxes(folderPath, state.activeTeam); - - return ( - <> - - history.push(folderUrl)} - onContextMenu={onContextMenu} - onKeyDown={event => { - if (event.keyCode === ENTER && !isRenaming && !isNewFolder) { - history.push(folderUrl, { - focus: 'FIRST_ITEM', - }); - } - }} - tabIndex={0} - style={{ - ...linkStyles, - paddingLeft: nestingLevel * 16, - }} - > - {subFolders.length ? ( - { - setFoldersVisibility(!foldersVisible); - event.stopPropagation(); - }} - css={css({ - width: 5, - height: '100%', - borderRadius: 0, - svg: { - transform: foldersVisible ? 'rotate(0deg)' : 'rotate(-90deg)', - transition: 'transform ease-in-out', - transitionDuration: theme => theme.speeds[2], - }, - })} - /> - ) : ( - - )} - - - - - - {isRenaming || isNewFolder ? ( -
    - -
    - ) : ( - - {name} - - )} -
    - -
    - - - {foldersVisible && ( - - {orderBy(subFolders, 'name') - .sort(a => 1) - .map(folder => ( - - ))} - - )} - - - ); -};