Merged feature/CE-882-add-functionality-of-sharing into integration/sprint-41

This commit is contained in:
2024-04-30 16:42:04 -05:00

View File

@ -25,8 +25,7 @@ import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QT
import {QJobComplete} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobComplete"; import {QJobComplete} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobComplete";
import {QJobError} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobError"; import {QJobError} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobError";
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord"; import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
import {Alert, Button} from "@mui/material"; import {Alert, Box, Button} from "@mui/material";
import Box from "@mui/material/Box";
import Dialog from "@mui/material/Dialog"; import Dialog from "@mui/material/Dialog";
import DialogActions from "@mui/material/DialogActions"; import DialogActions from "@mui/material/DialogActions";
import DialogContent from "@mui/material/DialogContent"; import DialogContent from "@mui/material/DialogContent";
@ -60,7 +59,7 @@ interface Props
view?: RecordQueryView; view?: RecordQueryView;
viewAsJson?: string; viewAsJson?: string;
viewOnChangeCallback?: (selectedSavedViewId: number) => void; viewOnChangeCallback?: (selectedSavedViewId: number) => void;
loadingSavedView: boolean loadingSavedView: boolean;
queryScreenUsage: QueryScreenUsage; queryScreenUsage: QueryScreenUsage;
} }
@ -69,6 +68,8 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
const navigate = useNavigate(); const navigate = useNavigate();
const [savedViews, setSavedViews] = useState([] as QRecord[]); const [savedViews, setSavedViews] = useState([] as QRecord[]);
const [yourSavedViews, setYourSavedViews] = useState([] as QRecord[]);
const [viewsSharedWithYou, setViewsSharedWithYou] = useState([] as QRecord[]);
const [savedViewsMenu, setSavedViewsMenu] = useState(null); const [savedViewsMenu, setSavedViewsMenu] = useState(null);
const [savedViewsHaveLoaded, setSavedViewsHaveLoaded] = useState(false); const [savedViewsHaveLoaded, setSavedViewsHaveLoaded] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
@ -91,7 +92,7 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
const CLEAR_OPTION = "New View"; const CLEAR_OPTION = "New View";
const NEW_REPORT_OPTION = "Create Report from Current View"; const NEW_REPORT_OPTION = "Create Report from Current View";
const {accentColor, accentColorLight} = useContext(QContext); const {accentColor, accentColorLight, userId: currentUserId} = useContext(QContext);
///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////
// this component is used by <RecordQuery> - but that component has different usages - // // this component is used by <RecordQuery> - but that component has different usages - //
@ -114,13 +115,13 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
{ {
setSavedViewsHaveLoaded(true); setSavedViewsHaveLoaded(true);
}); });
}, [location, tableMetaData]) }, [location, tableMetaData]);
const baseView = currentSavedView ? JSON.parse(currentSavedView.values.get("viewJson")) as RecordQueryView : tableDefaultView; const baseView = currentSavedView ? JSON.parse(currentSavedView.values.get("viewJson")) as RecordQueryView : tableDefaultView;
const viewDiffs = SavedViewUtils.diffViews(tableMetaData, baseView, view); const viewDiffs = SavedViewUtils.diffViews(tableMetaData, baseView, view);
let viewIsModified = false; let viewIsModified = false;
if(viewDiffs.length > 0) if (viewDiffs.length > 0)
{ {
viewIsModified = true; viewIsModified = true;
} }
@ -130,7 +131,7 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
*******************************************************************************/ *******************************************************************************/
async function loadSavedViews() async function loadSavedViews()
{ {
if (! tableMetaData) if (!tableMetaData)
{ {
return; return;
} }
@ -140,8 +141,24 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
let savedViews = await makeSavedViewRequest("querySavedView", formData); let savedViews = await makeSavedViewRequest("querySavedView", formData);
setSavedViews(savedViews); setSavedViews(savedViews);
}
const yourSavedViews: QRecord[] = [];
const viewsSharedWithYou: QRecord[] = [];
for (let i = 0; i < savedViews.length; i++)
{
const record = savedViews[i];
if (record.values.get("userId") == currentUserId)
{
yourSavedViews.push(record);
}
else
{
viewsSharedWithYou.push(record);
}
}
setYourSavedViews(yourSavedViews);
setViewsSharedWithYou(viewsSharedWithYou);
}
/******************************************************************************* /*******************************************************************************
@ -152,14 +169,13 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
setSaveFilterPopupOpen(false); setSaveFilterPopupOpen(false);
closeSavedViewsMenu(); closeSavedViewsMenu();
viewOnChangeCallback(record.values.get("id")); viewOnChangeCallback(record.values.get("id"));
if(isQueryScreen) if (isQueryScreen)
{ {
navigate(`${metaData.getTablePathByName(tableMetaData.name)}/savedView/${record.values.get("id")}`); navigate(`${metaData.getTablePathByName(tableMetaData.name)}/savedView/${record.values.get("id")}`);
} }
}; };
/******************************************************************************* /*******************************************************************************
** fired when a save option is selected from the save... button/dropdown combo ** fired when a save option is selected from the save... button/dropdown combo
*******************************************************************************/ *******************************************************************************/
@ -171,12 +187,12 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
setSaveFilterPopupOpen(true); setSaveFilterPopupOpen(true);
setIsSaveFilterAs(false); setIsSaveFilterAs(false);
setIsRenameFilter(false); setIsRenameFilter(false);
setIsDeleteFilter(false) setIsDeleteFilter(false);
switch(optionName) switch (optionName)
{ {
case SAVE_OPTION: case SAVE_OPTION:
if(currentSavedView == null) if (currentSavedView == null)
{ {
setSavedViewNameInputValue(""); setSavedViewNameInputValue("");
} }
@ -186,28 +202,28 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
setIsSaveFilterAs(true); setIsSaveFilterAs(true);
break; break;
case CLEAR_OPTION: case CLEAR_OPTION:
setSaveFilterPopupOpen(false) setSaveFilterPopupOpen(false);
viewOnChangeCallback(null); viewOnChangeCallback(null);
if(isQueryScreen) if (isQueryScreen)
{ {
navigate(metaData.getTablePathByName(tableMetaData.name)); navigate(metaData.getTablePathByName(tableMetaData.name));
} }
break; break;
case RENAME_OPTION: case RENAME_OPTION:
if(currentSavedView != null) if (currentSavedView != null)
{ {
setSavedViewNameInputValue(currentSavedView.values.get("label")); setSavedViewNameInputValue(currentSavedView.values.get("label"));
} }
setIsRenameFilter(true); setIsRenameFilter(true);
break; break;
case DELETE_OPTION: case DELETE_OPTION:
setIsDeleteFilter(true) setIsDeleteFilter(true);
break; break;
case NEW_REPORT_OPTION: case NEW_REPORT_OPTION:
createNewReport(); createNewReport();
break; break;
} }
} };
/******************************************************************************* /*******************************************************************************
@ -215,11 +231,11 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
*******************************************************************************/ *******************************************************************************/
function createNewReport() function createNewReport()
{ {
const defaultValues: {[key: string]: any} = {}; const defaultValues: { [key: string]: any } = {};
defaultValues.tableName = tableMetaData.name; defaultValues.tableName = tableMetaData.name;
let filterForBackend = JSON.parse(JSON.stringify(view.queryFilter)); let filterForBackend = JSON.parse(JSON.stringify(view.queryFilter));
filterForBackend = FilterUtils.prepQueryFilterForBackend(tableMetaData, filterForBackend); filterForBackend = FilterUtils.prepQueryFilterForBackend(tableMetaData, filterForBackend);
defaultValues.queryFilterJson = JSON.stringify(filterForBackend); defaultValues.queryFilterJson = JSON.stringify(filterForBackend);
defaultValues.columnsJson = JSON.stringify(view.queryColumns); defaultValues.columnsJson = JSON.stringify(view.queryColumns);
@ -227,7 +243,6 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
} }
/******************************************************************************* /*******************************************************************************
** fired when save or delete button saved on confirmation dialogs ** fired when save or delete button saved on confirmation dialogs
*******************************************************************************/ *******************************************************************************/
@ -247,7 +262,7 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
setSaveFilterPopupOpen(false); setSaveFilterPopupOpen(false);
setSaveOptionsOpen(false); setSaveOptionsOpen(false);
await(async() => await (async () =>
{ {
handleDropdownOptionClick(CLEAR_OPTION); handleDropdownOptionClick(CLEAR_OPTION);
})(); })();
@ -267,14 +282,14 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// strip away incomplete filters too, just for cleaner saved view filters // // strip away incomplete filters too, just for cleaner saved view filters //
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
FilterUtils.stripAwayIncompleteCriteria(viewObject.queryFilter) FilterUtils.stripAwayIncompleteCriteria(viewObject.queryFilter);
formData.append("viewJson", JSON.stringify(viewObject)); formData.append("viewJson", JSON.stringify(viewObject));
if (isSaveFilterAs || isRenameFilter || currentSavedView == null) if (isSaveFilterAs || isRenameFilter || currentSavedView == null)
{ {
formData.append("label", savedViewNameInputValue); formData.append("label", savedViewNameInputValue);
if(currentSavedView != null && isRenameFilter) if (currentSavedView != null && isRenameFilter)
{ {
formData.append("id", currentSavedView.values.get("id")); formData.append("id", currentSavedView.values.get("id"));
} }
@ -285,7 +300,7 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
formData.append("label", currentSavedView?.values.get("label")); formData.append("label", currentSavedView?.values.get("label"));
} }
const recordList = await makeSavedViewRequest("storeSavedView", formData); const recordList = await makeSavedViewRequest("storeSavedView", formData);
await(async() => await (async () =>
{ {
if (recordList && recordList.length > 0) if (recordList && recordList.length > 0)
{ {
@ -302,11 +317,11 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
catch (e: any) catch (e: any)
{ {
let message = JSON.stringify(e); let message = JSON.stringify(e);
if(typeof e == "string") if (typeof e == "string")
{ {
message = e; message = e;
} }
else if(typeof e == "object" && e.message) else if (typeof e == "object" && e.message)
{ {
message = e.message; message = e.message;
} }
@ -321,7 +336,6 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
} }
/******************************************************************************* /*******************************************************************************
** hides/shows the save options ** hides/shows the save options
*******************************************************************************/ *******************************************************************************/
@ -331,7 +345,6 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
}; };
/******************************************************************************* /*******************************************************************************
** closes save options menu (on clickaway) ** closes save options menu (on clickaway)
*******************************************************************************/ *******************************************************************************/
@ -346,7 +359,6 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
}; };
/******************************************************************************* /*******************************************************************************
** stores the current dialog input text to state ** stores the current dialog input text to state
*******************************************************************************/ *******************************************************************************/
@ -356,7 +368,6 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
}; };
/******************************************************************************* /*******************************************************************************
** closes current dialog ** closes current dialog
*******************************************************************************/ *******************************************************************************/
@ -366,7 +377,6 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
}; };
/******************************************************************************* /*******************************************************************************
** make a request to the backend for various savedView processes ** make a request to the backend for various savedView processes
*******************************************************************************/ *******************************************************************************/
@ -375,7 +385,7 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
///////////////////////// /////////////////////////
// fetch saved filters // // fetch saved filters //
///////////////////////// /////////////////////////
let savedViews = [] as QRecord[] let savedViews = [] as QRecord[];
try try
{ {
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
@ -386,12 +396,12 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
if (processResult instanceof QJobError) if (processResult instanceof QJobError)
{ {
const jobError = processResult as QJobError; const jobError = processResult as QJobError;
throw(jobError.error); throw (jobError.error);
} }
else else
{ {
const result = processResult as QJobComplete; const result = processResult as QJobComplete;
if(result.values.savedViewList) if (result.values.savedViewList)
{ {
for (let i = 0; i < result.values.savedViewList.length; i++) for (let i = 0; i < result.values.savedViewList.length; i++)
{ {
@ -403,7 +413,7 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
} }
catch (e) catch (e)
{ {
throw(e); throw (e);
} }
return (savedViews); return (savedViews);
@ -416,17 +426,27 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
const tooltipMaxWidth = (maxWidth: string) => const tooltipMaxWidth = (maxWidth: string) =>
{ {
return ({slotProps: { return ({
tooltip: { slotProps: {
sx: { tooltip: {
maxWidth: maxWidth sx: {
maxWidth: maxWidth
}
} }
} }
}}) });
} };
const menuTooltipAttribs = {...tooltipMaxWidth("250px"), placement: "left", enterDelay: 1000} as TooltipProps; const menuTooltipAttribs = {...tooltipMaxWidth("250px"), placement: "left", enterDelay: 1000} as TooltipProps;
let disabledBecauseNotOwner = false;
let notOwnerTooltipText = null;
if (currentSavedView && currentSavedView.values.get("userId") != currentUserId)
{
disabledBecauseNotOwner = true;
notOwnerTooltipText = "You may not save changes to this view, because you are not its owner.";
}
const renderSavedViewsMenu = tableMetaData && ( const renderSavedViewsMenu = tableMetaData && (
<Menu <Menu
anchorEl={savedViewsMenu} anchorEl={savedViewsMenu}
@ -443,75 +463,101 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
} }
{ {
isQueryScreen && hasStorePermission && isQueryScreen && hasStorePermission &&
<Tooltip {...menuTooltipAttribs} title={<>Save your current filters, columns and settings, for quick re-use at a later time.<br /><br />You will be prompted to enter a name if you choose this option.</>}> <Tooltip {...menuTooltipAttribs} title={notOwnerTooltipText ?? <>Save your current filters, columns and settings, for quick re-use at a later time.<br /><br />You will be prompted to enter a name if you choose this option.</>}>
<MenuItem onClick={() => handleDropdownOptionClick(SAVE_OPTION)}> <span>
<ListItemIcon><Icon>save</Icon></ListItemIcon> <MenuItem disabled={disabledBecauseNotOwner} onClick={() => handleDropdownOptionClick(SAVE_OPTION)}>
{currentSavedView ? "Save..." : "Save As..."} <ListItemIcon><Icon>save</Icon></ListItemIcon>
</MenuItem> {currentSavedView ? "Save..." : "Save As..."}
</MenuItem>
</span>
</Tooltip> </Tooltip>
} }
{ {
isQueryScreen && hasStorePermission && currentSavedView != null && isQueryScreen && hasStorePermission && currentSavedView != null &&
<Tooltip {...menuTooltipAttribs} title="Change the name for this saved view."> <Tooltip {...menuTooltipAttribs} title={notOwnerTooltipText ?? "Change the name for this saved view."}>
<MenuItem disabled={currentSavedView === null} onClick={() => handleDropdownOptionClick(RENAME_OPTION)}> <span>
<ListItemIcon><Icon>edit</Icon></ListItemIcon> <MenuItem disabled={currentSavedView === null || disabledBecauseNotOwner} onClick={() => handleDropdownOptionClick(RENAME_OPTION)}>
Rename... <ListItemIcon><Icon>edit</Icon></ListItemIcon>
</MenuItem> Rename...
</MenuItem>
</span>
</Tooltip> </Tooltip>
} }
{ {
isQueryScreen && hasStorePermission && currentSavedView != null && isQueryScreen && hasStorePermission && currentSavedView != null &&
<Tooltip {...menuTooltipAttribs} title="Save a new copy this view, with a different name, separate from the original."> <Tooltip {...menuTooltipAttribs} title="Save a new copy this view, with a different name, separate from the original.">
<MenuItem disabled={currentSavedView === null} onClick={() => handleDropdownOptionClick(DUPLICATE_OPTION)}> <span>
<ListItemIcon><Icon>content_copy</Icon></ListItemIcon> <MenuItem disabled={currentSavedView === null} onClick={() => handleDropdownOptionClick(DUPLICATE_OPTION)}>
Save As... <ListItemIcon><Icon>content_copy</Icon></ListItemIcon>
</MenuItem> Save As...
</MenuItem>
</span>
</Tooltip> </Tooltip>
} }
{ {
isQueryScreen && hasDeletePermission && currentSavedView != null && isQueryScreen && hasDeletePermission && currentSavedView != null &&
<Tooltip {...menuTooltipAttribs} title="Delete this saved view."> <Tooltip {...menuTooltipAttribs} title={notOwnerTooltipText ?? "Delete this saved view."}>
<MenuItem disabled={currentSavedView === null} onClick={() => handleDropdownOptionClick(DELETE_OPTION)}> <span>
<ListItemIcon><Icon>delete</Icon></ListItemIcon> <MenuItem disabled={currentSavedView === null || disabledBecauseNotOwner} onClick={() => handleDropdownOptionClick(DELETE_OPTION)}>
Delete... <ListItemIcon><Icon>delete</Icon></ListItemIcon>
</MenuItem> Delete...
</MenuItem>
</span>
</Tooltip> </Tooltip>
} }
{ {
isQueryScreen && isQueryScreen &&
<Tooltip {...menuTooltipAttribs} title="Create a new view of this table, resetting the filters and columns to their defaults."> <Tooltip {...menuTooltipAttribs} title="Create a new view of this table, resetting the filters and columns to their defaults.">
<MenuItem onClick={() => handleDropdownOptionClick(CLEAR_OPTION)}> <span>
<ListItemIcon><Icon>monitor</Icon></ListItemIcon> <MenuItem onClick={() => handleDropdownOptionClick(CLEAR_OPTION)}>
New View <ListItemIcon><Icon>monitor</Icon></ListItemIcon>
</MenuItem> New View
</MenuItem>
</span>
</Tooltip> </Tooltip>
} }
{ {
isQueryScreen && hasSavedReportsPermission && isQueryScreen && hasSavedReportsPermission &&
<Tooltip {...menuTooltipAttribs} title="Create a new Saved Report using your current view of this table as a starting point."> <Tooltip {...menuTooltipAttribs} title="Create a new Saved Report using your current view of this table as a starting point.">
<MenuItem onClick={() => handleDropdownOptionClick(NEW_REPORT_OPTION)}> <span>
<ListItemIcon><Icon>article</Icon></ListItemIcon> <MenuItem onClick={() => handleDropdownOptionClick(NEW_REPORT_OPTION)}>
Create Report from Current View <ListItemIcon><Icon>article</Icon></ListItemIcon>
</MenuItem> Create Report from Current View
</MenuItem>
</span>
</Tooltip> </Tooltip>
} }
{ {
isQueryScreen && <Divider/> isQueryScreen && <Divider />
} }
<MenuItem disabled style={{"opacity": "initial"}}><b>Your Saved Views</b></MenuItem> <MenuItem disabled style={{"opacity": "initial"}}><b>Your Saved Views</b></MenuItem>
{ {
savedViews && savedViews.length > 0 ? ( yourSavedViews && yourSavedViews.length > 0 ? (
savedViews.map((record: QRecord, index: number) => yourSavedViews.map((record: QRecord, index: number) =>
<MenuItem sx={{paddingLeft: "50px"}} key={`savedFiler-${index}`} onClick={() => handleSavedViewRecordOnClick(record)}> <MenuItem sx={{paddingLeft: "50px"}} key={`savedFiler-${index}`} onClick={() => handleSavedViewRecordOnClick(record)}>
{record.values.get("label")} {record.values.get("label")}
</MenuItem> </MenuItem>
) )
): ( ) : (
<MenuItem disabled sx={{opacity: "1 !important"}}> <MenuItem disabled sx={{opacity: "1 !important"}}>
<i>You do not have any saved views for this table.</i> <i>You do not have any saved views for this table.</i>
</MenuItem> </MenuItem>
) )
} }
<MenuItem disabled style={{"opacity": "initial"}}><b>Views Shared with you</b></MenuItem>
{
viewsSharedWithYou && viewsSharedWithYou.length > 0 ? (
viewsSharedWithYou.map((record: QRecord, index: number) =>
<MenuItem sx={{paddingLeft: "50px"}} key={`savedFiler-${index}`} onClick={() => handleSavedViewRecordOnClick(record)}>
{record.values.get("label")}
</MenuItem>
)
) : (
<MenuItem disabled sx={{opacity: "1 !important"}}>
<i>You do not have any views shared with you for this table.</i>
</MenuItem>
)
}
</Menu> </Menu>
); );
@ -520,7 +566,7 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
let buttonBorder = colors.grayLines.main; let buttonBorder = colors.grayLines.main;
let buttonColor = colors.gray.main; let buttonColor = colors.gray.main;
if(currentSavedView) if (currentSavedView)
{ {
if (viewIsModified) if (viewIsModified)
{ {
@ -548,23 +594,23 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
color: buttonColor, color: buttonColor,
backgroundColor: buttonBackground, backgroundColor: buttonBackground,
} }
} };
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/
function isSaveButtonDisabled(): boolean function isSaveButtonDisabled(): boolean
{ {
if(isSubmitting) if (isSubmitting)
{ {
return (true); return (true);
} }
const haveInputText = (savedViewNameInputValue != null && savedViewNameInputValue.trim() != "") const haveInputText = (savedViewNameInputValue != null && savedViewNameInputValue.trim() != "");
if(isSaveFilterAs || isRenameFilter || currentSavedView == null) if (isSaveFilterAs || isRenameFilter || currentSavedView == null)
{ {
if(!haveInputText) if (!haveInputText)
{ {
return (true); return (true);
} }
@ -593,7 +639,7 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
fontWeight: 500, fontWeight: 500,
fontSize: "0.875rem", fontSize: "0.875rem",
p: "0.5rem", p: "0.5rem",
... buttonStyles ...buttonStyles
}} }}
> >
<Icon sx={{mr: "0.5rem"}}>save</Icon> <Icon sx={{mr: "0.5rem"}}>save</Icon>
@ -624,7 +670,7 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
</> </>
} }
<Button disableRipple={true} sx={{color: colors.gray.main, ... linkButtonStyle}} onClick={() => handleDropdownOptionClick(CLEAR_OPTION)}>Reset All Changes</Button> <Button disableRipple={true} sx={{color: colors.gray.main, ...linkButtonStyle}} onClick={() => handleDropdownOptionClick(CLEAR_OPTION)}>Reset All Changes</Button>
</> </>
} }
{ {
@ -635,16 +681,20 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
{ {
viewDiffs.map((s: string, i: number) => <li key={i}>{s}</li>) viewDiffs.map((s: string, i: number) => <li key={i}>{s}</li>)
} }
</ul></>}> </ul>
{
notOwnerTooltipText && <i>{notOwnerTooltipText}</i>
}
</>}>
<Box display="inline" sx={{...linkButtonStyle, p: 0, cursor: "default", position: "relative", top: "-1px"}}>{viewDiffs.length} Unsaved Change{viewDiffs.length == 1 ? "" : "s"}</Box> <Box display="inline" sx={{...linkButtonStyle, p: 0, cursor: "default", position: "relative", top: "-1px"}}>{viewDiffs.length} Unsaved Change{viewDiffs.length == 1 ? "" : "s"}</Box>
</Tooltip> </Tooltip>
<Button disableRipple={true} sx={linkButtonStyle} onClick={() => handleDropdownOptionClick(SAVE_OPTION)}>Save&hellip;</Button> {disabledBecauseNotOwner ? <>&nbsp;&nbsp;</> : <Button disableRipple={true} sx={linkButtonStyle} onClick={() => handleDropdownOptionClick(SAVE_OPTION)}>Save&hellip;</Button>}
{/* vertical rule */} {/* vertical rule */}
<Box display="inline-block" borderLeft={`1px solid ${colors.grayLines.main}`} height="1rem" width="1px" position="relative" /> <Box display="inline-block" borderLeft={`1px solid ${colors.grayLines.main}`} height="1rem" width="1px" position="relative" />
<Button disableRipple={true} sx={{color: colors.gray.main, ... linkButtonStyle}} onClick={() => handleSavedViewRecordOnClick(currentSavedView)}>Reset All Changes</Button> <Button disableRipple={true} sx={{color: colors.gray.main, ...linkButtonStyle}} onClick={() => handleSavedViewRecordOnClick(currentSavedView)}>Reset All Changes</Button>
</> </>
} }
{ {
@ -663,16 +713,17 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
{ {
viewDiffs.map((s: string, i: number) => <li key={i}>{s}</li>) viewDiffs.map((s: string, i: number) => <li key={i}>{s}</li>)
} }
</ul></>}> </ul>
</>}>
<Box display="inline" ml="0.25rem" mr="0.25rem" sx={{...linkButtonStyle, p: 0, cursor: "default", position: "relative", top: "-1px"}}>with {viewDiffs.length} Change{viewDiffs.length == 1 ? "" : "s"}</Box> <Box display="inline" ml="0.25rem" mr="0.25rem" sx={{...linkButtonStyle, p: 0, cursor: "default", position: "relative", top: "-1px"}}>with {viewDiffs.length} Change{viewDiffs.length == 1 ? "" : "s"}</Box>
</Tooltip> </Tooltip>
<Button disableRipple={true} sx={{color: colors.gray.main, ... linkButtonStyle}} onClick={() => handleSavedViewRecordOnClick(currentSavedView)}>Reset Changes</Button> <Button disableRipple={true} sx={{color: colors.gray.main, ...linkButtonStyle}} onClick={() => handleSavedViewRecordOnClick(currentSavedView)}>Reset Changes</Button>
</> </>
} }
{/* vertical rule */} {/* vertical rule */}
<Box display="inline-block" ml="0.25rem" borderLeft={`1px solid ${colors.grayLines.main}`} height="1rem" width="1px" position="relative" /> <Box display="inline-block" ml="0.25rem" borderLeft={`1px solid ${colors.grayLines.main}`} height="1rem" width="1px" position="relative" />
<Button disableRipple={true} sx={{color: colors.gray.main, ... linkButtonStyle}} onClick={() => handleDropdownOptionClick(CLEAR_OPTION)}>Reset to New View</Button> <Button disableRipple={true} sx={{color: colors.gray.main, ...linkButtonStyle}} onClick={() => handleDropdownOptionClick(CLEAR_OPTION)}>Reset to New View</Button>
</Box> </Box>
} }
</Box> </Box>
@ -702,15 +753,15 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
) : ( ) : (
isSaveFilterAs ? ( isSaveFilterAs ? (
<DialogTitle id="alert-dialog-title">Save View As</DialogTitle> <DialogTitle id="alert-dialog-title">Save View As</DialogTitle>
):( ) : (
isRenameFilter ? ( isRenameFilter ? (
<DialogTitle id="alert-dialog-title">Rename View</DialogTitle> <DialogTitle id="alert-dialog-title">Rename View</DialogTitle>
):( ) : (
<DialogTitle id="alert-dialog-title">Update Existing View</DialogTitle> <DialogTitle id="alert-dialog-title">Update Existing View</DialogTitle>
) )
) )
) )
):( ) : (
<DialogTitle id="alert-dialog-title">Save New View</DialogTitle> <DialogTitle id="alert-dialog-title">Save New View</DialogTitle>
) )
} }
@ -721,12 +772,12 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
</Box> </Box>
) : ("")} ) : ("")}
{ {
(! currentSavedView || isSaveFilterAs || isRenameFilter) && ! isDeleteFilter ? ( (!currentSavedView || isSaveFilterAs || isRenameFilter) && !isDeleteFilter ? (
<Box> <Box>
{ {
isSaveFilterAs ? ( isSaveFilterAs ? (
<Box mb={3}>Enter a name for this new saved view.</Box> <Box mb={3}>Enter a name for this new saved view.</Box>
):( ) : (
<Box mb={3}>Enter a new name for this saved view.</Box> <Box mb={3}>Enter a new name for this saved view.</Box>
) )
} }
@ -744,10 +795,10 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
}} }}
/> />
</Box> </Box>
):( ) : (
isDeleteFilter ? ( isDeleteFilter ? (
<Box>Are you sure you want to delete the view {`'${currentSavedView?.values.get("label")}'`}?</Box> <Box>Are you sure you want to delete the view {`'${currentSavedView?.values.get("label")}'`}?</Box>
):( ) : (
<Box>Are you sure you want to update the view {`'${currentSavedView?.values.get("label")}'`}?</Box> <Box>Are you sure you want to update the view {`'${currentSavedView?.values.get("label")}'`}?</Box>
) )
) )
@ -759,7 +810,7 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
isDeleteFilter ? isDeleteFilter ?
<QDeleteButton onClickHandler={handleFilterDialogButtonOnClick} disabled={isSubmitting} /> <QDeleteButton onClickHandler={handleFilterDialogButtonOnClick} disabled={isSubmitting} />
: :
<QSaveButton label="Save" onClickHandler={handleFilterDialogButtonOnClick} disabled={isSaveButtonDisabled()}/> <QSaveButton label="Save" onClickHandler={handleFilterDialogButtonOnClick} disabled={isSaveButtonDisabled()} />
} }
</DialogActions> </DialogActions>
</Dialog> </Dialog>