Add sample JoyRide walkthrough.
This commit is contained in:
@@ -299,6 +299,7 @@ function Header({
|
||||
},
|
||||
{
|
||||
key: 'jobssubmenu',
|
||||
id: 'header-jobs',
|
||||
icon: <Icon component={FaCarCrash} />,
|
||||
label: t('menus.header.jobs'),
|
||||
children: [
|
||||
@@ -319,6 +320,7 @@ function Header({
|
||||
},
|
||||
{
|
||||
key: 'availablejobs',
|
||||
id: 'header-jobs-available',
|
||||
icon: <ImportOutlined />,
|
||||
label: <Link to="/manage/available">{t('menus.header.availablejobs')}</Link>,
|
||||
},
|
||||
|
||||
@@ -16,12 +16,18 @@ import useLocalStorage from "../../utils/useLocalStorage";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import ChatOpenButton from "../chat-open-button/chat-open-button.component";
|
||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||
import { setJoyRideSteps } from "../../redux/application/application.actions";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
});
|
||||
|
||||
export function JobsList({bodyshop}) {
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setJoyRideSteps: (steps) => dispatch(setJoyRideSteps(steps)),
|
||||
|
||||
});
|
||||
|
||||
export function JobsList({bodyshop,setJoyRideSteps}) {
|
||||
const searchParams = queryString.parse(useLocation().search);
|
||||
const {selected} = searchParams;
|
||||
const selectedBreakpoint = Object.entries(Grid.useBreakpoint())
|
||||
@@ -352,51 +358,75 @@ export function JobsList({bodyshop}) {
|
||||
};
|
||||
|
||||
return (
|
||||
<Card
|
||||
title={t("titles.bc.jobs-active")}
|
||||
extra={
|
||||
<Space wrap>
|
||||
<Button onClick={() => refetch()}>
|
||||
<SyncOutlined/>
|
||||
</Button>
|
||||
<Input.Search
|
||||
placeholder={t("general.labels.search")}
|
||||
onChange={(e) => {
|
||||
setSearchText(e.target.value);
|
||||
}}
|
||||
value={searchText}
|
||||
enterButton
|
||||
/>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<Table
|
||||
loading={loading}
|
||||
pagination={{defaultPageSize: 50}}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={jobs}
|
||||
scroll={{
|
||||
x: selectedBreakpoint ? scrollMapper[selectedBreakpoint[0]] : "100%",
|
||||
}}
|
||||
rowSelection={{
|
||||
onSelect: (record) => {
|
||||
handleOnRowClick(record);
|
||||
},
|
||||
selectedRowKeys: [selected],
|
||||
type: "radio",
|
||||
}}
|
||||
onChange={handleTableChange}
|
||||
onRow={(record, rowIndex) => {
|
||||
return {
|
||||
onClick: (event) => {
|
||||
handleOnRowClick(record);
|
||||
},
|
||||
};
|
||||
}}
|
||||
<Card
|
||||
id="active-jobs-list"
|
||||
title={t('titles.bc.jobs-active')}
|
||||
extra={
|
||||
<Space wrap>
|
||||
<Button
|
||||
onClick={() =>
|
||||
setJoyRideSteps([
|
||||
{
|
||||
target: '#active-jobs-list',
|
||||
content: 'This is where you will see all work coming in and currently here.',
|
||||
},
|
||||
{
|
||||
target: '#header-jobs',
|
||||
spotlightClicks :true,
|
||||
disableOverlayClose :true,
|
||||
content: 'The jobs menu lets you access additional pages to see more information. You can import new jobs, search all jobs, or manage your current production.',
|
||||
},
|
||||
{
|
||||
target: '#header-jobs-available',
|
||||
content: 'You can find jobs to import here.',
|
||||
},
|
||||
|
||||
])
|
||||
}
|
||||
>
|
||||
Start Walk Through
|
||||
</Button>
|
||||
<Button onClick={() => refetch()}>
|
||||
<SyncOutlined />
|
||||
</Button>
|
||||
<Input.Search
|
||||
placeholder={t('general.labels.search')}
|
||||
onChange={(e) => {
|
||||
setSearchText(e.target.value);
|
||||
}}
|
||||
value={searchText}
|
||||
enterButton
|
||||
/>
|
||||
</Card>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<Table
|
||||
loading={loading}
|
||||
pagination={{ defaultPageSize: 50 }}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={jobs}
|
||||
scroll={{
|
||||
x: selectedBreakpoint ? scrollMapper[selectedBreakpoint[0]] : '100%',
|
||||
}}
|
||||
rowSelection={{
|
||||
onSelect: (record) => {
|
||||
handleOnRowClick(record);
|
||||
},
|
||||
selectedRowKeys: [selected],
|
||||
type: 'radio',
|
||||
}}
|
||||
onChange={handleTableChange}
|
||||
onRow={(record, rowIndex) => {
|
||||
return {
|
||||
onClick: (event) => {
|
||||
handleOnRowClick(record);
|
||||
},
|
||||
};
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, null)(JobsList);
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(JobsList);
|
||||
|
||||
@@ -1,29 +1,32 @@
|
||||
import {FloatButton, Layout, Spin} from "antd";
|
||||
import { FloatButton, Layout, Spin } from "antd";
|
||||
// import preval from "preval.macro";
|
||||
import React, {lazy, Suspense, useEffect, useState} from "react";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {connect} from "react-redux";
|
||||
import {Link, Route, Routes} from "react-router-dom";
|
||||
import {createStructuredSelector} from "reselect";
|
||||
import React, { lazy, Suspense, useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { Link, Route, Routes } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import BreadCrumbs from "../../components/breadcrumbs/breadcrumbs.component";
|
||||
import ChatAffixContainer from "../../components/chat-affix/chat-affix.container";
|
||||
import ConflictComponent from "../../components/conflict/conflict.component";
|
||||
import ErrorBoundary from "../../components/error-boundary/error-boundary.component";
|
||||
//import FooterComponent from "../../components/footer/footer.component";
|
||||
//Component Imports
|
||||
import * as Sentry from "@sentry/react";
|
||||
import Joyride from 'react-joyride';
|
||||
import TestComponent from "../../components/_test/test.page";
|
||||
import HeaderContainer from "../../components/header/header.container";
|
||||
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
|
||||
import PartnerPingComponent from "../../components/partner-ping/partner-ping.component";
|
||||
import PrintCenterModalContainer from "../../components/print-center-modal/print-center-modal.container";
|
||||
import ShopSubStatusComponent from "../../components/shop-sub-status/shop-sub-status.component";
|
||||
import TestComponent from "../../components/_test/test.page";
|
||||
import {requestForToken} from "../../firebase/firebase.utils";
|
||||
import {selectBodyshop, selectInstanceConflict,} from "../../redux/user/user.selectors";
|
||||
import * as Sentry from "@sentry/react";
|
||||
import { requestForToken } from "../../firebase/firebase.utils";
|
||||
import { selectBodyshop, selectInstanceConflict, } from "../../redux/user/user.selectors";
|
||||
|
||||
import "./manage.page.styles.scss";
|
||||
import UpdateAlert from "../../components/update-alert/update-alert.component";
|
||||
import { setJoyRideFinished } from "../../redux/application/application.actions.js";
|
||||
import { selectEnableJoyRide, selectJoyRideSteps } from "../../redux/application/application.selectors.js";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr.js";
|
||||
import "./manage.page.styles.scss";
|
||||
|
||||
const JobsPage = lazy(() => import("../jobs/jobs.page"));
|
||||
|
||||
@@ -179,12 +182,22 @@ const TtApprovals = lazy(() =>
|
||||
|
||||
const {Content, Footer} = Layout;
|
||||
|
||||
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
conflict: selectInstanceConflict,
|
||||
bodyshop: selectBodyshop,
|
||||
enableJoyRide: selectEnableJoyRide,
|
||||
joyRideSteps: selectJoyRideSteps
|
||||
});
|
||||
|
||||
export function Manage({conflict, bodyshop}) {
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setJoyRideFinished: (steps) => dispatch(setJoyRideFinished(steps)),
|
||||
|
||||
});
|
||||
|
||||
export function Manage({conflict, bodyshop,enableJoyRide,joyRideSteps,setJoyRideFinished}) {
|
||||
const {t} = useTranslation();
|
||||
const [chatVisible] = useState(false);
|
||||
|
||||
@@ -469,46 +482,65 @@ export function Manage({conflict, bodyshop}) {
|
||||
else PageContent = AppRouteTable;
|
||||
|
||||
return (
|
||||
<>
|
||||
<ChatAffixContainer bodyshop={bodyshop} chatVisible={chatVisible}/>
|
||||
<Layout style={{minHeight: '100vh'}} className="layout-container">
|
||||
<UpdateAlert/>
|
||||
<HeaderContainer/>
|
||||
<Content className="content-container">
|
||||
<PartnerPingComponent/>
|
||||
<Sentry.ErrorBoundary fallback={<ErrorBoundary/>} showDialog>
|
||||
{PageContent}
|
||||
</Sentry.ErrorBoundary>
|
||||
<>
|
||||
<ChatAffixContainer bodyshop={bodyshop} chatVisible={chatVisible} />
|
||||
<Layout style={{ minHeight: '100vh' }} className="layout-container">
|
||||
<UpdateAlert />
|
||||
<HeaderContainer />
|
||||
<Content className="content-container">
|
||||
<Joyride
|
||||
debug
|
||||
run={enableJoyRide}
|
||||
steps={joyRideSteps}
|
||||
continuous
|
||||
hideCloseButton
|
||||
scrollToFirstStep
|
||||
showProgress
|
||||
showSkipButton
|
||||
callback={(props) => {
|
||||
if (props.action === 'reset') {
|
||||
setJoyRideFinished();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<PartnerPingComponent />
|
||||
<Sentry.ErrorBoundary fallback={<ErrorBoundary />} showDialog>
|
||||
{PageContent}
|
||||
</Sentry.ErrorBoundary>
|
||||
|
||||
<FloatButton.BackTop style={{right: 100, bottom: 25}}/>
|
||||
|
||||
</Content>
|
||||
<Footer>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
margin: "1rem 0rem",
|
||||
}}
|
||||
>
|
||||
<div style={{display: "flex"}}>
|
||||
<div>
|
||||
{`${InstanceRenderManager({imex: t("titles.imexonline"), rome: t("titles.romeonline"), promanager:t("titles.promanager")})} ${
|
||||
import.meta.env.VITE_APP_GIT_SHA || 'Local Build'
|
||||
} - ${import.meta.env.VITE_APP_GIT_SHA_DATE}`}
|
||||
</div>
|
||||
<div id="noticeable-widget" style={{marginLeft: "1rem"}}/>
|
||||
</div>
|
||||
<Link to="/disclaimer" target="_blank" style={{color: "#ccc"}}>
|
||||
Disclaimer & Notices
|
||||
</Link>
|
||||
</div>
|
||||
</Footer>
|
||||
</Layout>
|
||||
</>
|
||||
<FloatButton.BackTop style={{ right: 100, bottom: 25 }} />
|
||||
</Content>
|
||||
<Footer>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
margin: '1rem 0rem',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex' }}>
|
||||
{`Joy Ride Status: ${enableJoyRide}`}
|
||||
<div>
|
||||
{`${InstanceRenderManager({
|
||||
imex: t('titles.imexonline'),
|
||||
rome: t('titles.romeonline'),
|
||||
promanager: t('titles.promanager'),
|
||||
})} ${import.meta.env.VITE_APP_GIT_SHA || 'Local Build'} - ${
|
||||
import.meta.env.VITE_APP_GIT_SHA_DATE
|
||||
}`}
|
||||
</div>
|
||||
<div id="noticeable-widget" style={{ marginLeft: '1rem' }} />
|
||||
</div>
|
||||
<Link to="/disclaimer" target="_blank" style={{ color: '#ccc' }}>
|
||||
Disclaimer & Notices
|
||||
</Link>
|
||||
</div>
|
||||
</Footer>
|
||||
</Layout>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, null)(Manage);
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Manage);
|
||||
|
||||
@@ -67,3 +67,11 @@ export const setUpdateAvailable = (isUpdateAvailable) => ({
|
||||
type: ApplicationActionTypes.SET_UPDATE_AVAILABLE,
|
||||
payload: isUpdateAvailable,
|
||||
});
|
||||
export const setJoyRideSteps = (steps) => ({
|
||||
type: ApplicationActionTypes.SET_JOYRIDE_STEPS,
|
||||
payload: steps,
|
||||
});
|
||||
export const setJoyRideFinished = () => ({
|
||||
type: ApplicationActionTypes.SET_JOYRIDE_FINISHED,
|
||||
//payload: isUpdateAvailable,
|
||||
});
|
||||
|
||||
@@ -15,6 +15,8 @@ const INITIAL_STATE = {
|
||||
},
|
||||
jobReadOnly: false,
|
||||
partnerVersion: null,
|
||||
enableJoyRide: false,
|
||||
joyRideSteps: []
|
||||
};
|
||||
|
||||
const applicationReducer = (state = INITIAL_STATE, action) => {
|
||||
@@ -87,6 +89,12 @@ const applicationReducer = (state = INITIAL_STATE, action) => {
|
||||
case ApplicationActionTypes.SET_PROBLEM_JOBS: {
|
||||
return {...state, problemJobs: action.payload};
|
||||
}
|
||||
case ApplicationActionTypes.SET_JOYRIDE_STEPS: {
|
||||
return {...state, enableJoyRide:true, joyRideSteps: action.payload}
|
||||
}
|
||||
case ApplicationActionTypes.SET_JOYRIDE_FINISHED: {
|
||||
return {...state, enableJoyRide:false, joyRideSteps: []}
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -52,3 +52,11 @@ export const selectUpdateAvailable = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.updateAvailable
|
||||
);
|
||||
export const selectEnableJoyRide= createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.enableJoyRide
|
||||
);
|
||||
export const selectJoyRideSteps= createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.joyRideSteps
|
||||
);
|
||||
|
||||
@@ -12,6 +12,8 @@ const ApplicationActionTypes = {
|
||||
SET_ONLINE_STATUS: "SET_ONLINE_STATUS",
|
||||
INSERT_AUDIT_TRAIL: "INSERT_AUDIT_TRAIL",
|
||||
SET_PROBLEM_JOBS: "SET_PROBLEM_JOBS",
|
||||
SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE"
|
||||
SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE",
|
||||
SET_JOYRIDE_STEPS: "SET_JOYRIDE_STEPS",
|
||||
SET_JOYRIDE_FINISHED:"SET_JOYRIDE_FINISHED"
|
||||
};
|
||||
export default ApplicationActionTypes;
|
||||
|
||||
Reference in New Issue
Block a user