From 010c5615dddd045b1e9ca56594e2b36d9d7a40d6 Mon Sep 17 00:00:00 2001 From: Kevin Charles Date: Tue, 11 Apr 2023 22:24:05 +0000 Subject: [PATCH] Public Editor updates --- public/api/getPortfolioActivityData.php | 27 +- .../HeaderControls/PublicNavigation.jsx | 53 ++++ .../MenuPanelCaps/PublicEditorInfoCap.jsx | 47 ++++ src/Tools/_framework/NewToolRoot.jsx | 229 ++++++++--------- src/Tools/_framework/Panels/NewMenuPanel.jsx | 239 ++++++++++-------- .../_framework/Panels/NewSupportPanel.jsx | 169 ++++++++----- 6 files changed, 462 insertions(+), 302 deletions(-) create mode 100644 src/Tools/_framework/HeaderControls/PublicNavigation.jsx create mode 100644 src/Tools/_framework/MenuPanelCaps/PublicEditorInfoCap.jsx diff --git a/public/api/getPortfolioActivityData.php b/public/api/getPortfolioActivityData.php index 2bfea8b261..187f400e74 100644 --- a/public/api/getPortfolioActivityData.php +++ b/public/api/getPortfolioActivityData.php @@ -88,14 +88,6 @@ // WHERE doenetId='$doenetId' // AND courseId = (SELECT courseId FROM course WHERE portfolioCourseForUserId = '$userId') // "; - $sql = " - SELECT imagePath, - label, - userCanViewSource, - isPublic - FROM course_content - WHERE doenetId='$doenetId' - "; // $sql = " // SELECT imagePath, // label, @@ -103,12 +95,27 @@ // isPublic // FROM course_content // WHERE doenetId='$doenetId' - // AND courseId = (SELECT courseId FROM course WHERE portfolioCourseForUserId = '$userId') // "; + $sql = " + SELECT cc.imagePath, + cc.label, + cc.userCanViewSource, + cc.isPublic, + c.portfolioCourseForUserId + FROM course_content AS cc + LEFT JOIN course AS c + ON c.courseId = cc.courseId + WHERE doenetId='$doenetId' + "; + $result = $conn->query($sql); if ($result->num_rows > 0) { $row = $result->fetch_assoc(); + $isPortfolioCourse = '0'; + if ($row['portfolioCourseForUserId'] != ""){ + $isPortfolioCourse = '1'; + } $activityData = [ 'doenetId' => $doenetId, 'imagePath' => $row['imagePath'], @@ -119,6 +126,8 @@ 'isNew' => false, 'pageDoenetId' => $pageDoenetId, 'courseId' => $courseId, + 'isPortfolioCourse' => $isPortfolioCourse, + ]; } else { $success = false; diff --git a/src/Tools/_framework/HeaderControls/PublicNavigation.jsx b/src/Tools/_framework/HeaderControls/PublicNavigation.jsx new file mode 100644 index 0000000000..5983d043bd --- /dev/null +++ b/src/Tools/_framework/HeaderControls/PublicNavigation.jsx @@ -0,0 +1,53 @@ +import React, { Suspense } from 'react'; +import Button from '../../../_reactComponents/PanelHeaderComponents/Button'; +import { useNavigate, useLoaderData } from 'react-router'; + +export default function PublicNavigation() { + const navigate = useNavigate(); + // const { isPortfolioCourse, doenetId, courseId } = useLoaderData(); + const { signedIn, portfolioCourseId } = useLoaderData(); + return ( + loading Breadcrumbs...}> +
+
+
+ ); +} diff --git a/src/Tools/_framework/MenuPanelCaps/PublicEditorInfoCap.jsx b/src/Tools/_framework/MenuPanelCaps/PublicEditorInfoCap.jsx new file mode 100644 index 0000000000..6cd2d55cd3 --- /dev/null +++ b/src/Tools/_framework/MenuPanelCaps/PublicEditorInfoCap.jsx @@ -0,0 +1,47 @@ +import { Box, Image } from '@chakra-ui/react'; +import React from 'react'; +import { useLoaderData } from 'react-router'; + +export async function loader({ params }) { + const doenetId = params.doenetId; + const response = await fetch( + `/api/getPortfolioActivityData.php?doenetId=${doenetId}`, + ); + const data = await response.json(); + + return data.activityData; +} + +export default function PublicEditorInfoCap() { + let { activityData } = useLoaderData(); + let imagePath = '/activity_default.jpg'; + if (activityData?.imagePath != null) { + imagePath = activityData?.imagePath; + } + return ( + <> + + Activity Image + +
+ Public Activity Editor +
+ {/*
{data.label}
*/} + + ); +} diff --git a/src/Tools/_framework/NewToolRoot.jsx b/src/Tools/_framework/NewToolRoot.jsx index 9014fa9897..a784f5732f 100644 --- a/src/Tools/_framework/NewToolRoot.jsx +++ b/src/Tools/_framework/NewToolRoot.jsx @@ -40,8 +40,6 @@ const ToolContainer = styled(animated.div)` color: var(--canvastext); `; - - export const profileAtom = atom({ key: 'profileAtom', default: selector({ @@ -107,7 +105,9 @@ export default function ToolRoot() { NotFound: lazy(() => import('./ToolPanels/NotFound')), AccountSettings: lazy(() => import('./ToolPanels/AccountSettings')), HomePanel: lazy(() => import('./ToolPanels/HomePanel')), - PublicActivityViewer: lazy(() => import('./ToolPanels/PublicActivityViewer')), + PublicActivityViewer: lazy(() => + import('./ToolPanels/PublicActivityViewer'), + ), CourseCards: lazy(() => import('./ToolPanels/CourseCards')), SignIn: lazy(() => import('./ToolPanels/SignIn')), SignOut: lazy(() => import('./ToolPanels/SignOut')), @@ -122,7 +122,9 @@ export default function ToolRoot() { GradebookAttempt: lazy(() => import('./ToolPanels/GradebookAttempt')), EditorViewer: lazy(() => import('./ToolPanels/EditorViewer')), AssignmentViewer: lazy(() => import('./ToolPanels/AssignmentViewer')), - DraftAssignmentViewer: lazy(() => import('./ToolPanels/DraftAssignmentViewer')), + DraftAssignmentViewer: lazy(() => + import('./ToolPanels/DraftAssignmentViewer'), + ), DataPanel: lazy(() => import('./ToolPanels/DataPanel')), SurveyDataViewer: lazy(() => import('./ToolPanels/SurveyDataViewer')), DoenetMLEditor: lazy(() => import('./ToolPanels/DoenetMLEditor')), @@ -130,10 +132,14 @@ export default function ToolRoot() { ChooseLearnerPanel: lazy(() => import('./ToolPanels/ChooseLearnerPanel')), SignInRedirector: lazy(() => import('./ToolPanels/SignInRedirector')), EndExamPanel: lazy(() => import('./ToolPanels/EndExamPanel')), - EndPlacementExamPanel: lazy(() => import('./ToolPanels/EndPlacementExamPanel')), - WelcomePlacementExam: lazy(() => import('./ToolPanels/WelcomePlacementExam')), - GuestDoenetMLEditor:lazy(() => import('./ToolPanels/GuestDoenetMLEditor')), - GuestEditorViewer:lazy(() => import('./ToolPanels/GuestEditorViewer')), + EndPlacementExamPanel: lazy(() => + import('./ToolPanels/EndPlacementExamPanel'), + ), + WelcomePlacementExam: lazy(() => + import('./ToolPanels/WelcomePlacementExam'), + ), + GuestDoenetMLEditor: lazy(() => import('./ToolPanels/GuestDoenetMLEditor')), + GuestEditorViewer: lazy(() => import('./ToolPanels/GuestEditorViewer')), RolesEditor: lazy(() => import('./ToolPanels/RoleEditor')), }).current; @@ -149,12 +155,13 @@ export default function ToolRoot() { DashboardBreadCrumb: lazy(() => import('./HeaderControls/DashboardBreadCrumb'), ), - PeopleBreadCrumb: lazy(() => - import('./HeaderControls/PeopleBreadCrumb'), - ), + PeopleBreadCrumb: lazy(() => import('./HeaderControls/PeopleBreadCrumb')), DataBreadCrumb: lazy(() => import('./HeaderControls/DataBreadCrumb')), EditorBreadCrumb: lazy(() => import('./HeaderControls/EditorBreadCrumb')), - PortfolioBreadCrumb: lazy(() => import('./HeaderControls/PortfolioBreadCrumb')), + PortfolioBreadCrumb: lazy(() => + import('./HeaderControls/PortfolioBreadCrumb'), + ), + PublicNavigation: lazy(() => import('./HeaderControls/PublicNavigation')), GradebookBreadCrumb: lazy(() => import('./HeaderControls/GradebookBreadCrumb'), ), @@ -164,9 +171,9 @@ export default function ToolRoot() { AssignmentNewAttempt: lazy(() => import('./HeaderControls/AssignmentNewAttempt'), ), - ActivityNavigationButtons: lazy(() => - import('./HeaderControls/ActivityNavigationButtons') - ) + ActivityNavigationButtons: lazy(() => + import('./HeaderControls/ActivityNavigationButtons'), + ), }).current; const LazyFooterObj = useRef({ @@ -182,59 +189,23 @@ export default function ToolRoot() { - - - + + + - - - + + + - - - + + + @@ -273,36 +244,31 @@ export default function ToolRoot() { - + - + - + - + - + @@ -333,7 +299,7 @@ export default function ToolRoot() { fallback={ - + } @@ -397,7 +363,6 @@ export default function ToolRoot() { //

insert keyboard here

- return ( <> @@ -483,15 +448,15 @@ let navigationObj = { }, }, umn: { - default:{ + default: { defaultTool: 'signIn', }, - signIn:{ + signIn: { pageName: 'signIn', currentMainPanel: 'SignInRedirector', displaySettings: false, hasNoMenuPanel: true, - } + }, }, portfolioeditor: { editor: { @@ -560,7 +525,11 @@ let navigationObj = { currentMenus: ['CreditAchieved', 'TimerMenu', 'ActivityDates'], menusTitles: ['Credit Achieved', 'Time Remaining', 'Details'], menusInitOpen: [true, true, false], - headerControls: ['AssignmentBreadCrumb', 'AssignmentNewAttempt','ActivityNavigationButtons'], + headerControls: [ + 'AssignmentBreadCrumb', + 'AssignmentNewAttempt', + 'ActivityNavigationButtons', + ], waitForMenuSuppression: true, footer: { height: 250, open: false, component: 'MathInputKeyboard' }, }, @@ -669,9 +638,9 @@ let navigationObj = { menuPanelCap: 'DriveInfoCap', // currentMenus: ['AddDriveItems','CutCopyPasteMenu'], // menusTitles: ['Add Items','Cut, Copy and Paste'], - currentMenus: ['CutCopyPasteMenu','AddDriveItems'], - menusTitles: ['Cut, Copy and Paste','Add Items'], - menusInitOpen: [true,true], + currentMenus: ['CutCopyPasteMenu', 'AddDriveItems'], + menusTitles: ['Cut, Copy and Paste', 'Add Items'], + menusInitOpen: [true, true], headerControls: ['NavigationBreadCrumb'], onLeave: 'NavigationLeave', waitForMenuSuppression: true, @@ -720,10 +689,9 @@ let navigationObj = { data: { pageName: 'data', menuPanelCap: 'DataCap', - currentMainPanel: 'DataPanel', + currentMainPanel: 'DataPanel', headerControls: ['DataBreadCrumb'], }, - }, home: { default: { @@ -750,33 +718,30 @@ let navigationObj = { hasNoMenuPanel: true, }, }, - public:{ - default:{ - pageName:"PublicActivityViewer", - currentMenus:[], - menusTitles:[], - menusInitOpen:[], - currentMainPanel:"PublicActivityViewer", - supportPanelOptions:[], - supportPanelTitles:[], - supportPanelIndex:0, + public: { + default: { + pageName: 'PublicActivityViewer', + currentMenus: [], + menusTitles: [], + menusInitOpen: [], + currentMainPanel: 'PublicActivityViewer', + supportPanelOptions: [], + supportPanelTitles: [], + supportPanelIndex: 0, hasNoMenuPanel: true, }, editor: { //singleFile pageName: 'GuestEditor', + menuPanelCap: 'PublicEditorInfoCap', currentMainPanel: 'GuestEditorViewer', - currentMenus: [ - 'PageVariant', - ], - menusTitles: [ - 'Page Variant', - ], + currentMenus: ['PageVariant'], + menusTitles: ['Page Variant'], menusInitOpen: [false], supportPanelOptions: ['GuestDoenetMLEditor'], supportPanelTitles: ['DoenetML Editor'], supportPanelIndex: 0, - headerControls: ['ViewerUpdateButton'], + headerControls: ['PublicNavigation', 'ViewerUpdateButton'], footer: { height: 250, open: false, component: 'MathInputKeyboard' }, }, }, @@ -900,7 +865,6 @@ function RootController(props) { const [suppressMenus, setSuppressMenus] = useRecoilState(suppressMenusAtom); const setPanelsInfoAtom = useSetRecoilState(panelsInfoAtom); - let lastPageToolView = useRef({ page: 'init', tool: '', view: '' }); let backPageToolView = useRef({ page: 'init', tool: '', view: '' }); let backParams = useRef({}); @@ -936,17 +900,21 @@ function RootController(props) { // console.log("\n>>>===RootController") //initialProportion - let initialProportion = navigationObj[recoilPageToolView.page]?.[recoilPageToolView.tool]?.initialProportion + let initialProportion = + navigationObj[recoilPageToolView.page]?.[recoilPageToolView.tool] + ?.initialProportion; - useEffect(()=>{ + useEffect(() => { let nextInitialProportion = initialProportion; - if (!nextInitialProportion){ nextInitialProportion = 0.5} - setPanelsInfoAtom((prev)=>{ - let next = {...prev} - next.proportion = nextInitialProportion; - return next; - }) - },[initialProportion]) + if (!nextInitialProportion) { + nextInitialProportion = 0.5; + } + setPanelsInfoAtom((prev) => { + let next = { ...prev }; + next.proportion = nextInitialProportion; + return next; + }); + }, [initialProportion]); //Suppress Menu change test let isSuppressMenuChange = !arraysEqual( @@ -962,13 +930,16 @@ function RootController(props) { }; // console.log("navigationObj[recoilPageToolView.page][recoilPageToolView.tool].currentMenus",navigationObj[recoilPageToolView.page][recoilPageToolView.tool].currentMenus) nextMenusAndPanels.currentMenus = [ - ...navigationObj[recoilPageToolView.page][recoilPageToolView.tool].currentMenus, + ...navigationObj[recoilPageToolView.page][recoilPageToolView.tool] + .currentMenus, ]; nextMenusAndPanels.menusTitles = [ - ...navigationObj[recoilPageToolView.page][recoilPageToolView.tool].menusTitles, + ...navigationObj[recoilPageToolView.page][recoilPageToolView.tool] + .menusTitles, ]; nextMenusAndPanels.menusInitOpen = [ - ...navigationObj[recoilPageToolView.page][recoilPageToolView.tool].menusInitOpen, + ...navigationObj[recoilPageToolView.page][recoilPageToolView.tool] + .menusInitOpen, ]; if (suppressMenus.length > 0) { @@ -1179,11 +1150,10 @@ function RootController(props) { return null; } - const LoadingFallback = styled.div` background-color: var(--canvas); border-radius: 4px; - display: ${props => props.display ? props.display : "flex"}; + display: ${(props) => (props.display ? props.display : 'flex')}; justify-content: center; align-items: center; font-size: 2em; @@ -1191,7 +1161,7 @@ const LoadingFallback = styled.div` height: 100%; `; -const bouncingDonut = keyframes ` +const bouncingDonut = keyframes` from { transform: translate3d(0, 0px, 0);} to { transform: translate3d(0, 20px, 0);} `; @@ -1247,7 +1217,7 @@ const BreadcrumbContainer = styled.ul` background-color: var(--canvas); `; -const shimmerAnimation = keyframes ` +const shimmerAnimation = keyframes` from { background-position: -468px 0 } @@ -1270,41 +1240,50 @@ const BreadcrumbOutline = styled.li` animation-name: ${shimmerAnimation}; animation-timing-function: linear; background: var(--canvas); - background: linear-gradient(to right, var(--mainGray) 8%, var(--mainGray) 18%, var(--mainGray) 33%); + background: linear-gradient( + to right, + var(--mainGray) 8%, + var(--mainGray) 18%, + var(--mainGray) 33% + ); background-size: 1000px 640px; position: relative; `; -const movingGradient = keyframes ` +const movingGradient = keyframes` 0% { background-position: -250px 0; } 100% { background-position: 250px 0; } `; -const Table = styled.table ` +const Table = styled.table` border-radius: 5px; margin: 8px; `; -const Tr = styled.tr ` +const Tr = styled.tr` /* border-bottom: 2px solid var(--canvastext); */ `; -const Td = styled.td ` +const Td = styled.td` height: 40px; &.Td3 { width: 100%; } - `; -const TBody = styled.tbody ``; -const Td3Span = styled.span ` +const TBody = styled.tbody``; +const Td3Span = styled.span` display: block; height: 14px; border-radius: 5px; - background: linear-gradient(to right, var(--mainGray) 20%, var(--mainGray) 50%, var(--mainGray) 80%); + background: linear-gradient( + to right, + var(--mainGray) 20%, + var(--mainGray) 50%, + var(--mainGray) 80% + ); background-size: 500px 100px; animation-name: ${movingGradient}; animation-duration: 1s; animation-iteration-count: infinite; animation-timing-function: linear; animation-fill-mode: forwards; -`; \ No newline at end of file +`; diff --git a/src/Tools/_framework/Panels/NewMenuPanel.jsx b/src/Tools/_framework/Panels/NewMenuPanel.jsx index 78cd502c97..7ca063eaef 100644 --- a/src/Tools/_framework/Panels/NewMenuPanel.jsx +++ b/src/Tools/_framework/Panels/NewMenuPanel.jsx @@ -25,8 +25,6 @@ export const selectedMenuPanelAtom = atom({ default: null, }); - - const MenuPanelsWrapper = styled.div` grid-area: menuPanel; display: flex; @@ -42,7 +40,7 @@ const MenuPanelsWrapper = styled.div` const MenuPanelsCap = styled.div` width: 240px; height: 35px; - color:var(--canvastext); + color: var(--canvastext); background: var(--canvas); display: flex; justify-content: space-between; @@ -86,16 +84,16 @@ const Branding = styled.div` // `; const MenuPanelsCapComponent = styled.div` -width: 240px; -background-color: var(--canvas); -color: var(--canvastext); -border-top: 1px solid #e2e2e2; -border-top: 1px solid #e2e2e2; -border-bottom: 2px solid #e2e2e2; -margin-bottom: -2px; -position: sticky; -top: 35; -z-index: 1; + width: 240px; + background-color: var(--canvas); + color: var(--canvastext); + border-top: 1px solid #e2e2e2; + border-top: 1px solid #e2e2e2; + border-bottom: 2px solid #e2e2e2; + margin-bottom: -2px; + position: sticky; + top: 35; + z-index: 1; `; const MenuHeaderButton = styled.button` @@ -111,20 +109,20 @@ const MenuHeaderButton = styled.button` `; const CloseButton = styled.button` -background-color: #1A5A99; -height: 35px; -width: 20px; -color: white; -border: none; -// display: inline-block; -position: static; -left: 220px; -cursor: pointer; -z-index: 2; -&:focus { - outline: 2px solid var(--mainBlue); - outline-offset: 2px; -} + background-color: #1a5a99; + height: 35px; + width: 20px; + color: white; + border: none; + // display: inline-block; + position: static; + left: 220px; + cursor: pointer; + z-index: 2; + &:focus { + outline: 2px solid var(--mainBlue); + outline-offset: 2px; + } `; const EditMenuPanels = styled.button` @@ -140,7 +138,7 @@ const EditMenuPanels = styled.button` const MenuPanelTitle = styled.button` width: 240px; height: 35px; - color:var(--canvastext); + color: var(--canvastext); background: var(--canvas); display: flex; justify-content: center; @@ -148,7 +146,9 @@ const MenuPanelTitle = styled.button` border: 0px solid var(--canvas); // border-top: 1px solid var(--canvastext); border-bottom: ${(props) => - props.isOpen ? '2px solid var(--canvastext)' : '0px solid var(--canvastext)'}; + props.isOpen + ? '2px solid var(--canvastext)' + : '0px solid var(--canvastext)'}; margin-top: 2px; &:focus { outline: 2px solid var(--canvastext); @@ -176,29 +176,30 @@ const HomeButton = styled.button` font-size: 20px; `; -function SelectionMenu(props){ +function SelectionMenu(props) { // console.log("child", props.children); - return <> -
+
{/*

Current Selection

*/} {props.children}
- ; + ); } function Menu(props) { @@ -215,10 +216,10 @@ function Menu(props) { return ( <> - setIsOpen((was) => !was)} id="menu-title" data-test={`${props.type} Menu`} @@ -227,7 +228,7 @@ function Menu(props) {
-
-
-
-
-