fixbugwithselectordropdownaddedclockedinlist

This commit is contained in:
jfrye122
2023-05-13 13:56:44 -04:00
parent 2d17623bdf
commit 66fa8196af
10 changed files with 505 additions and 106 deletions

View File

@@ -53,16 +53,16 @@ export function CostCenterSelect(props) {
selectedTextStyle={styles.selectedTextStyle} selectedTextStyle={styles.selectedTextStyle}
inputSearchStyle={styles.inputSearchStyle} inputSearchStyle={styles.inputSearchStyle}
iconStyle={styles.iconStyle} iconStyle={styles.iconStyle}
data={costCenters}
search search
maxHeight={300} maxHeight={300}
labelField="label" labelField="label"
valueField="value" valueField="value"
placeholder={!isFocus ? "Select Cost Center" : "..."} placeholder={!isFocus ? "Select Cost Center" : "..."}
searchPlaceholder="Search..." searchPlaceholder="Search..."
value={props.currentValue?.value}
onFocus={() => setIsFocus(true)} onFocus={() => setIsFocus(true)}
onBlur={() => setIsFocus(false)} onBlur={() => setIsFocus(false)}
data={costCenters}
value={props.currentValue?.value}
onChange={(item) => { onChange={(item) => {
props.onValueSelected(item); props.onValueSelected(item);
//setValue(item.value); //setValue(item.value);

View File

@@ -1,5 +1,5 @@
import { useLazyQuery } from "@apollo/client"; import { useLazyQuery } from "@apollo/client";
import React, { forwardRef, useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import _ from "lodash"; import _ from "lodash";
@@ -12,17 +12,24 @@ import { Dropdown } from "react-native-element-dropdown";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component"; import { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component";
///This Component is for testing select. This is not for prod. Justin
export function JobIdSearchSelect( export function JobIdSearchSelect(
convertedOnly = false, props
notInvoiced = false, // //currentValue,
notExported = true, // ...restProps
clm_no = false,
onValueSelected,
currentValue,
...restProps
) { ) {
// console.log("JobIdSearchSelectprops:", props);
const notExported =
props.notExported !== undefined ? props.notExported : true;
const notInvoiced =
props.notInvoiced !== undefined ? props.notInvoiced : false;
const convertedOnly =
props.convertedOnly !== undefined ? props.convertedOnly : false;
const clm_no = props.clm_no !== undefined ? props.clm_no : false;
// console.log("notExported:", notExported);
// console.log("notInvoiced:", notInvoiced);
// console.log("convertedOnly:", convertedOnly);
// console.log("clm_no:", clm_no);
const { t } = useTranslation(); const { t } = useTranslation();
const [theOptions, setTheOptions] = useState([]); const [theOptions, setTheOptions] = useState([]);
@@ -33,19 +40,18 @@ export function JobIdSearchSelect(
const [callIdSearch, { loading: idLoading, error: idError, data: idData }] = const [callIdSearch, { loading: idLoading, error: idError, data: idData }] =
useLazyQuery(SEARCH_JOBS_BY_ID_FOR_AUTOCOMPLETE); useLazyQuery(SEARCH_JOBS_BY_ID_FOR_AUTOCOMPLETE);
const [callSearch, { loading, error, data }] = useLazyQuery( const [callSearch, { loading, error, data }] = useLazyQuery(
SEARCH_JOBS_FOR_AUTOCOMPLETE, SEARCH_JOBS_FOR_AUTOCOMPLETE,
{} {}
); );
const executeSearch = (v) => { const executeSearch = (v) => {
console.log("executeSearchWithV:", v); // console.log("executeSearchWithV:", v);
if (v && v !== "") callSearch(v); if (v && v !== "") callSearch(v);
}; };
const debouncedExecuteSearch = _.debounce(executeSearch, 500); const debouncedExecuteSearch = _.debounce(executeSearch, 500);
const handleSearch = (value) => { const handleSearch = (value) => {
console.log("handleSearchWithValue:", value); // console.log("handleSearchWithValue:", value);
debouncedExecuteSearch({ debouncedExecuteSearch({
variables: { variables: {
search: value, search: value,
@@ -60,52 +66,59 @@ export function JobIdSearchSelect(
}); });
}; };
useEffect(() => { // useEffect(() => {
console.log("useEfectDependentOn: restProps.value, callIdSearch", restProps); // console.log("useEfectDependentOn: restProps.value, callIdSearch", restProps);
if (restProps.value) { // if (restProps.value) {
console.log("restPropsValue:", restProps.value); // console.log("restPropsValue:", restProps.value);
callIdSearch({ variables: { id: restProps.value } }); // callIdSearch({ variables: { id: restProps.value } });
} // }
}, [restProps.value, callIdSearch]); // }, [restProps.value, callIdSearch]);
useEffect(() => { useEffect(() => {
console.log("useEfectDependentOn: [data, idData]"); // console.log("useEfectDependentOn: [data, idData]");
console.log("idDataValue:", (idData && idData.jobs_by_pk ? [idData.jobs_by_pk] : [])); // console.log( "idDataValue:", idData && idData.jobs_by_pk ? [idData.jobs_by_pk] : []);
console.log("dataValue:", (data && data.search_jobs ? data.search_jobs : [])); // console.log("dataValue:", data && data.search_jobs ? data.search_jobs : []);
setTheOptions(
_.uniqBy( if (data) {
[ setTheOptions(
...(idData && idData.jobs_by_pk ? [idData.jobs_by_pk] : []), _.uniqBy(
...(data && data.search_jobs ? data.search_jobs : []), [
], ...(idData && idData.jobs_by_pk ? [idData.jobs_by_pk] : []),
"id" ...(data && data.search_jobs ? data.search_jobs : []),
) ],
); "id"
)
);
}
}, [data, idData]); }, [data, idData]);
useEffect(() => { useEffect(() => {
console.log("useEfectDependentOn: [theOptions]"); // console.log("useEfectDependentOn: [theOptions]");
var count = Object.keys(theOptions).length; var count = Object.keys(theOptions).length;
console.log("useEfectDependentOn: [theOptions] count:", count);
let selectDataArray = []; let selectDataArray = [];
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
// let o = theOptions[i];
selectDataArray.push({ selectDataArray.push({
value: theOptions[i].id, value: theOptions[i].id,
label: theOptions[i].ro_number, label: `${clm_no && theOptions[i].clm_no ? `${theOptions[i].clm_no} | ` : ""}${
theOptions[i].ro_number || t("general.labels.na")
// `${clm_no && o.clm_no ? `${o.clm_no} | ` : ""}${ } | ${OwnerNameDisplayFunction(theOptions[i])} | ${theOptions[i].v_model_yr || ""} ${theOptions[i].v_make_desc || ""} ${
// o.ro_number || t("general.labels.na") theOptions[i].v_model_desc || ""
// } | ${OwnerNameDisplayFunction(o)} | ${o.v_model_yr || ""} ${o.v_make_desc || ""} ${ }`,
// o.v_model_desc || ""
// }`,
}); });
} }
setSelectorData(selectDataArray); setSelectorData(selectDataArray);
}, [theOptions]); }, [theOptions]);
// useEffect(() => {
// console.log("useEffectonselectedvaluechange:", selectedvalue.value);
// if (typeof onJobSelected !== "undefined") {
// console.log("onJobSelected:", selectedvalue.value);
// onJobSelected(selectedvalue.value);
// }
// }, [selectedvalue]);
return ( return (
<View style={styles.container}> <View style={styles.container}>
<Dropdown <Dropdown
@@ -114,29 +127,41 @@ export function JobIdSearchSelect(
selectedTextStyle={styles.selectedTextStyle} selectedTextStyle={styles.selectedTextStyle}
inputSearchStyle={styles.inputSearchStyle} inputSearchStyle={styles.inputSearchStyle}
iconStyle={styles.iconStyle} iconStyle={styles.iconStyle}
data={selectorData}
search search
maxHeight={300} maxHeight={300}
labelField="label" labelField="label"
valueField="value" valueField="value"
placeholder={!isFocus ? "Job Id to Post Against" : "..."} placeholder={!isFocus ? "Job Id to Post Against" : "..."}
searchPlaceholder="Search..." searchPlaceholder="Search..."
value={selectedvalue}//{selectedvalue}
onFocus={() => setIsFocus(true)} onFocus={() => setIsFocus(true)}
onBlur={() => setIsFocus(false)} onBlur={() => setIsFocus(false)}
onChange={(item) => { data={selectorData}
console.log("onChangefired!!!!"); value={selectedvalue} //{selectedvalue}
console.log("itemSelected", item); onChange={(item) => props.onJobSelected(item)}//TODO: add setIsFocus(false); to this
setSelectedValue(item.value); // {
// onValueSelected(item); // console.log("onValueSelected!!!!");
//console.log(item); // // (item) => {onJobSelected(item.value)};
// console.log("onChangefired!!!!");
// console.log("itemSelected", item);
// onJobSelected(item.value);
// setSelectedValue(item.value);
// console.log("onValueSelected",onValueSelected);
// if (onValueSelected){
// console.log("onValueSelected!!!!");
// }
//console.log(item);
// setSelectedValue(item.value); // setSelectedValue(item.value);
// if (onValueSelected) onValueSelected(item.value); // if (onValueSelected) onValueSelected(item.value);
setIsFocus(false);
}} // setIsFocus(false);
// }}
onChangeText={(search) => { onChangeText={(search) => {
if (search && search !== "") {
console.log("onChangeTextFired!!!!"); console.log("onChangeTextFired!!!!");
handleSearch(search); handleSearch(search);
}
}} }}
/> />
{/* {theOptions ? console.log(theOptions): null} */} {/* {theOptions ? console.log(theOptions): null} */}

View File

@@ -0,0 +1,73 @@
import React from "react";
import { useTranslation } from "react-i18next";
import { FlatList, RefreshControl, StyleSheet, Text, View } from "react-native";
import { Card, DataTable } from "react-native-paper";
export default function LaborAllocationsTable({ job, loading, refetch }) {
const { t } = useTranslation();
if (!job) {
<Card>
<Text>Job is not defined.</Text>
</Card>;
}
const onRefresh = async () => {
return refetch();
};
return (
<View style={{ flex: 1 }}>
<DataTable>
<DataTable.Header>
<DataTable.Title style={{ flex: 4 }}>
{t("jobdetail.labels.lines_desc")}
</DataTable.Title>
<DataTable.Title style={{ flex: 2 }}>
{t("jobdetail.labels.lines_lbr_ty")}
</DataTable.Title>
<DataTable.Title style={{ flex: 1 }}>
{t("jobdetail.labels.lines_lb_hrs")}
</DataTable.Title>
<DataTable.Title style={{ flex: 2 }}>
{t("jobdetail.labels.lines_part_type")}
</DataTable.Title>
<DataTable.Title style={{ flex: 1 }}>
{t("jobdetail.labels.lines_qty")}
</DataTable.Title>
</DataTable.Header>
</DataTable>
<FlatList
data={job.joblines}
refreshControl={
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
}
keyExtractor={(item) => item.id}
renderItem={(object) => (
<DataTable.Row>
<DataTable.Cell style={{ flex: 4 }}>
{object.item.line_desc}
</DataTable.Cell>
<DataTable.Cell style={{ flex: 2 }}>
{object.item.mod_lbr_ty &&
t(`jobdetail.lbr_types.${object.item.mod_lbr_ty}`)}
</DataTable.Cell>
<DataTable.Cell style={{ flex: 1 }}>
{object.item.mod_lb_hrs}
</DataTable.Cell>
<DataTable.Cell style={{ flex: 2 }}>
{object.item.part_type &&
t(`jobdetail.part_types.${object.item.part_type}`)}
</DataTable.Cell>
<DataTable.Cell style={{ flex: 1 }}>
{object.item.part_qty}
</DataTable.Cell>
</DataTable.Row>
)}
/>
</View>
);
}
const localStyles = StyleSheet.create({});

View File

@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useState } from "react"; import React, { useCallback, useEffect, useState } from "react";
import { View, Text } from "react-native"; import { View, Text } from "react-native";
import axios from "axios";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { employeeGetRatesStart } from "../../redux/employee/employee.actions"; import { employeeGetRatesStart } from "../../redux/employee/employee.actions";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
@@ -16,13 +16,14 @@ import { Button } from "react-native-paper";
import { useQuery } from "@apollo/client"; import { useQuery } from "@apollo/client";
import ErrorDisplay from "../error-display/error-display.component"; import ErrorDisplay from "../error-display/error-display.component";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import { JobSearchSelect } from "../Selects/select-job-name"; import { JobIdSearchSelect } from "../Selects/select-job-id";
import { CostCenterSelect } from "../Selects/select-cost-center"; import { CostCenterSelect } from "../Selects/select-cost-center";
import { import {
selectCurrentTimeTicketJob, selectCurrentTimeTicketJob,
selectCurrentTimeTicketJobId, selectCurrentTimeTicketJobId,
} from "../../redux/timetickets/timetickets.selectors"; } from "../../redux/timetickets/timetickets.selectors";
import { JobIdSearchSelect } from "../Selects/select-job-id"; import moment from "moment";
import { EmployeeClockedInList } from "../time-ticket-lists/employee-clockedin-list.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
currentEmployee: selectCurrentEmployee, currentEmployee: selectCurrentEmployee,
@@ -51,7 +52,7 @@ export function ScreenTimeTicketBrowser({
}) { }) {
//const employeeId = currentEmployee.technician.id; //const employeeId = currentEmployee.technician.id;
const [currentSCC, setCurrentSCC] = useState(null); const [currentSCC, setCurrentSCC] = useState(null);
const [currentSJob, setCurrentSJob] = useState(null); // const [currentSJob, setCurrentSJob] = useState(null);
const [currentSJobId, setCurrentSJobId] = useState(null); const [currentSJobId, setCurrentSJobId] = useState(null);
// const { error, data } = useQuery(QUERY_EMPLOYEE_BY_ID, { // const { error, data } = useQuery(QUERY_EMPLOYEE_BY_ID, {
@@ -60,43 +61,65 @@ export function ScreenTimeTicketBrowser({
// const signingErrorMsg = error ? (<ErrorDisplay errorMessage={error.message} />) : null; // const signingErrorMsg = error ? (<ErrorDisplay errorMessage={error.message} />) : null;
// const signingErrorMsg = signingError ? (<ErrorDisplay errorMessage={signingError} />) : null; // const signingErrorMsg = signingError ? (<ErrorDisplay errorMessage={signingError} />) : null;
const wrapperSetCurrentSJobState = useCallback(val => { // const wrapperSetCurrentSJobState = useCallback(
setCurrentSJob(val); // (val) => {
}, [setCurrentSJob]); // setCurrentSJobId(val);
// },
// [setCurrentSJobId]
// );
const getRates = (currentEmployee) => { const getRates = (currentEmployee) => {
employeeGetRatesStart(currentEmployee.technician.id); employeeGetRatesStart(currentEmployee.technician.id);
}; };
const createTheTimeTicketOBJ = ( const createTheTimeTicketOBJ = async (
currentEmployee, currentEmployee,
currentBodyshop, currentBodyshop,
currentSCC, currentSCC,
currentSJob,
currentSJobId currentSJobId
) => { ) => {
console.log("currentSCC", currentSCC.value); const theTime = (await axios.post("/utils/time")).data;
console.log("currentSJob", currentSJob.value); if (currentBodyshop) console.log("bodyshopid", currentBodyshop?.id);
console.log("currentSJobId", currentSJobId.value); if (currentEmployee) console.log("employeeid", currentEmployee?.technician.id);
console.log("bodyshopid", currentBodyshop.id); if (theTime) console.log("date", moment(theTime).format("YYYY-MM-DD"));
console.log("employeeid", currentEmployee.technician.id); // if (currentSJob) console.log("currentSJob", currentSJob?.value);
console.log(currentBodyshop); if (currentSJobId) console.log("jobid or currentSJobId", currentSJobId?.value);
if (currentSCC) console.log("cost_center or currentSCC", currentSCC?.value);
//if(currentBodyshop)console.log(currentBodyshop);
if (currentBodyshop)
console.log(
"ciecacode",
currentBodyshop?.cdk_dealerid || currentBodyshop?.pbs_serialnumber
? currentSCC?.value
: Object.keys(
currentBodyshop.md_responsibility_centers.defaults.costs
).find((key) => {
return (
currentBodyshop.md_responsibility_centers.defaults.costs[
key
] === currentSCC?.value
);
})
);
if (currentEmployee)
console.log("flat_rate", currentEmployee?.technician?.flat_rate);
if (currentSCC) console.log("rate or currentSCC", currentSCC?.rate);
// const temp = { // const temp = {
// timeTicketInput: [ // timeTicketInput: [
// { // {
// bodyshopid: currentBodyshop?.id, //have bodyshopid: currentBodyshop?.id,
// employeeid: currentEmployee?.technician?.id, //have employeeid: currentEmployee?.technician?.id,
// date: "2023-05-11", //moment(theTime).format("YYYY-MM-DD"), //have date: "2023-05-11", //moment(theTime).format("YYYY-MM-DD"),
// //clockon: moment(theTime), // //clockon: moment(theTime),
// jobid: "temp",//values.jobid, // jobid: "temp",//values.jobid,
// cost_center: "temp",//values.cost_center, //have cost_center: "temp",//values.cost_center,
// ciecacode: currentBodyshop?.cdk_dealerid || currentBodyshop?.pbs_serialnumber //have ciecacode: currentBodyshop?.cdk_dealerid || currentBodyshop?.pbs_serialnumber
// ? values.cost_center // ? values.cost_center
// : Object.keys(currentBodyshop.md_responsibility_centers.defaults.costs).find((key) => { // : Object.keys(currentBodyshop.md_responsibility_centers.defaults.costs).find((key) => {
// return (currentBodyshop.md_responsibility_centers.defaults.costs[key] === "temp");//values.cost_center); // return (currentBodyshop.md_responsibility_centers.defaults.costs[key] === "temp");//values.cost_center);
// }), // }),
// flat_rate: currentEmployee.technician.flat_rate, //have flat_rate: currentEmployee.technician.flat_rate,
// rate: 1, //have rate: 1,
// }, // },
// ], // ],
// }; // };
@@ -111,7 +134,7 @@ export function ScreenTimeTicketBrowser({
loading={loaderGettingRates} loading={loaderGettingRates}
//onPress={() => getRates(currentEmployee)} //onPress={() => getRates(currentEmployee)}
onPress={() => onPress={() =>
createTheTimeTicketOBJ(currentEmployee, currentBodyshop, currentSCC) createTheTimeTicketOBJ(currentEmployee, currentBodyshop, currentSCC, currentSJobId)
} }
> >
<Text>text here</Text> <Text>text here</Text>
@@ -119,14 +142,7 @@ export function ScreenTimeTicketBrowser({
{/* {signingErrorMsg} */} {/* {signingErrorMsg} */}
<JobIdSearchSelect <JobIdSearchSelect
currentValue={currentSJobId} currentValue={currentSJobId}
//onValueSelected={setCurrentSJobId} onJobSelected={setCurrentSJobId}
convertedOnly={!currentBodyshop.tt_allow_post_to_invoiced}
notExported={!currentBodyshop.tt_allow_post_to_invoiced}
/>
<JobSearchSelect
currentValue={currentSJob}
onValueSelected={setCurrentSJob}
convertedOnly={!currentBodyshop.tt_allow_post_to_invoiced} convertedOnly={!currentBodyshop.tt_allow_post_to_invoiced}
notExported={!currentBodyshop.tt_allow_post_to_invoiced} notExported={!currentBodyshop.tt_allow_post_to_invoiced}
/> />
@@ -139,10 +155,11 @@ export function ScreenTimeTicketBrowser({
mode="outlined" mode="outlined"
//loading={loaderClockIn} //loading={loaderClockIn}
//onPress={() => clockIn()} //onPress={() => clockIn()}
> >
<Text>Clock In</Text> <Text>Clock In</Text>
</Button> </Button>
<EmployeeClockedInList technician={currentEmployee} />
</View> </View>
); );
} }

View File

@@ -0,0 +1,94 @@
import { Ionicons } from "@expo/vector-icons";
import { useNavigation } from "@react-navigation/native";
import React from "react";
import { useTranslation } from "react-i18next";
import { Button, List, Title, Card, Text } from "react-native-paper";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component";
import { DateTimeFormatter } from "../../util/DateFormater";
// const mapStateToProps = createStructuredSelector({});
// const mapDispatchToProps = (dispatch) => ({
// setCameraJobId: (id) => dispatch(setCameraJobId(id)),
// setCameraJob: (job) => dispatch(setCameraJob(job)),
// });
export function ClockedinListItem({ ticket }) {
const { t } = useTranslation();
const navigation = useNavigation();
const onPress = () => {
// logImEXEvent("imexmobile_view_job_detail");
// navigation.push("JobDetail", {
// jobId: item.id,
// title: item.ro_number || t("general.labels.na"),
// job: item,
// });
console.log("ClockedinListItem, onPress called");
};
return (
<Card style={{ margin: 8 }}>
<Card.Title
title={`${
ticket.job.ro_number || t("general.labels.na")
} ${OwnerNameDisplayFunction(ticket.job)}`}
/>
<Card.Content>
<Text>Vehicle :
{`${ticket.job.v_model_yr || ""} ${
ticket.job.v_make_desc || ""
} ${ticket.job.v_model_desc || ""}`}
</Text>
<Text>
Clocked In : <DateTimeFormatter>{ticket.clockon}</DateTimeFormatter>
</Text>
<Text>
Cost Center : {ticket.cost_center === "timetickets.labels.shift"
? t(ticket.cost_center)
: ticket.cost_center}
</Text>
</Card.Content>
<Card.Actions>
{/* <TechClockOffButton
jobId={ticket.jobid}
timeTicketId={ticket.id}
completedCallback={refetch}
/> */}
<Button
mode="outlined" onPress={() => onPress}>Clock Out</Button>
</Card.Actions>
</Card>
// <List.Item
// onPress={onPress}
// title={<Title>{item.ro_number || t("general.labels.na")}</Title>}
// descriptionNumberOfLines={2}
// description={`${item.ownr_fn || ""} ${item.ownr_ln || ""} ${
// item.ownr_co_nm || ""
// } - ${item.v_model_yr || ""} ${item.v_make_desc || ""} ${
// item.v_model_desc || ""
// }`}
// right={({ style }) => (
// <Button
// style={[style, { alignSelf: "center" }]}
// onPress={() => {
// logImEXEvent("imexmobile_setcamerajobid_row");
// setCameraJobId(item.id);
// setCameraJob(item);
// navigation.navigate("MediaBrowserTab");
// }}
// >
// <Ionicons
// style={[style, { alignSelf: "center" }]}
// name="ios-add"
// size={32}
// color="dodgerblue"
// />
// </Button>
// )}
// />
);
}
export default connect(null, null)(ClockedinListItem);

View File

@@ -0,0 +1,111 @@
import { connect } from "react-redux";
import { selectCurrentEmployee, selectTechnician } from "../../redux/employee/employee.selectors";
import { QUERY_ACTIVE_TIME_TICKETS } from "../../graphql/timetickets.queries";
import { ActivityIndicator,Button, List, Modal, Portal, Searchbar } from "react-native-paper";
import ErrorDisplay from "../error-display/error-display.component";
import { View,Text,FlatList, RefreshControl, } from "react-native";
import { useQuery } from "@apollo/client";
import { createStructuredSelector } from "reselect";
import { useTranslation } from "react-i18next";
import { ClockedinListItem } from "../time-ticket-items/clockedin-list-item.component";
const mapStateToProps = createStructuredSelector({
technician: selectTechnician,
//currentEmployee: selectCurrentEmployee,
});
const mapDispatchToProps = (dispatch) => ({});
export function EmployeeClockedInList({ technician }) {
const { t } = useTranslation();
const { loading, error, data, refetch } = useQuery(QUERY_ACTIVE_TIME_TICKETS, {
variables: {
employeeId: technician?.id,
},
skip: !technician,
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
}
);
if (loading) return <ActivityIndicator color="dodgerblue" size="large" />;
if (error) return <ErrorDisplay errorMessage={error.message} />;
//if (error) return <AlertComponent message={error.message} type="error" />;
console.log("QUERY_ACTIVE_TIME_TICKETS data",data)
const onRefresh = async () => {
return refetch();
};
return (
<View>
{data.timetickets.length > 0 ? (
<View>
<Text>You are already clocked in to the following job(s):</Text>
<FlatList data={data.timetickets}
refreshControl={<RefreshControl refreshing={loading} onRefresh={onRefresh} />}
renderItem={(object) => <ClockedinListItem ticket={object.item} />} />
</View>
) : null}
</View>
// <div>
// {data.timetickets.length > 0 ? (
// <div>
// <Typography.Title level={2}>
// {t("timetickets.labels.alreadyclockedon")}
// </Typography.Title>
// <List
// grid={{
// gutter: 32,
// xs: 1,
// sm: 2,
// md: 3,
// lg: 4,
// xl: 5,
// xxl: 6,
// }}
// dataSource={data.timetickets || []}
// renderItem={(ticket) => (
// <List.Item>
// <Card
// title={
// <Link to={`/tech/joblookup?selected=${ticket.job.id}`}>
// {`${
// ticket.job.ro_number || t("general.labels.na")
// } ${OwnerNameDisplayFunction(ticket.job)}`}
// </Link>
// }
// actions={[
// <TechClockOffButton
// jobId={ticket.jobid}
// timeTicketId={ticket.id}
// completedCallback={refetch}
// />,
// ]}
// >
// <div>
// {`
// ${ticket.job.v_model_yr || ""} ${
// ticket.job.v_make_desc || ""
// } ${ticket.job.v_model_desc || ""}`}
// </div>
// <DataLabel label={t("timetickets.fields.clockon")}>
// <DateTimeFormatter>{ticket.clockon}</DateTimeFormatter>
// </DataLabel>
// <DataLabel label={t("timetickets.fields.cost_center")}>
// {ticket.cost_center === "timetickets.labels.shift"
// ? t(ticket.cost_center)
// : ticket.cost_center}
// </DataLabel>
// </Card>
// </List.Item>
// )}
// ></List>
// </div>
// ) : null}
// </div>
);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(EmployeeClockedInList);

View File

@@ -1,12 +1,12 @@
import { Formik } from "formik"; import { Formik } from "formik";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { StyleSheet, Text,View, ScrollView } from "react-native"; import { StyleSheet, Text, View, ScrollView } from "react-native";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { Button, Dialog, TextInput } from "react-native-paper"; import { Button, Dialog, TextInput } from "react-native-paper";
import { CostCenterSelect } from "../Selects/select-cost-center"; import { CostCenterSelect } from "../Selects/select-cost-center";
import { JobSearchSelect } from "../Selects/select-job-name"; import { JobIdSearchSelect } from "../Selects/select-job-id";
import DateTimePickerModal from "react-native-modal-datetime-picker"; import DateTimePickerModal from "react-native-modal-datetime-picker";
import { import {
selectCurrentEmployee, selectCurrentEmployee,
@@ -26,7 +26,7 @@ const mapStateToProps = createStructuredSelector({
export function TimeTicketCreate({ export function TimeTicketCreate({
currentEmployee, currentEmployee,
currentRatesNCostCenters, currentRatesNCostCenters,
currentBodyshop currentBodyshop,
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -35,10 +35,14 @@ export function TimeTicketCreate({
const [currentSCC, setCurrentSCC] = useState(null); const [currentSCC, setCurrentSCC] = useState(null);
const [currentSJob, setCurrentSJob] = useState(null); const [currentSJob, setCurrentSJob] = useState(null);
const [currentSJobId, setCurrentSJobId] = useState(null);
const wrapperSetCurrentSJobState = useCallback(val => { const wrapperSetCurrentSJobState = useCallback(
setCurrentSJob(val); (val) => {
}, [setCurrentSJob]); setCurrentSJob(val);
},
[setCurrentSJob]
);
const showDatePicker = () => { const showDatePicker = () => {
setDatePickerVisibility(true); setDatePickerVisibility(true);
@@ -48,7 +52,7 @@ export function TimeTicketCreate({
}; };
const handleConfirm = (date) => { const handleConfirm = (date) => {
setDate2(date); setDate2(date);
//console.warn("A date has been picked: ", date); //console.war1n("A date has been picked: ", date);
hideDatePicker(); hideDatePicker();
}; };
const formSubmit = (values) => { const formSubmit = (values) => {
@@ -72,14 +76,23 @@ export function TimeTicketCreate({
> >
{({ handleChange, handleBlur, handleSubmit, values }) => ( {({ handleChange, handleBlur, handleSubmit, values }) => (
<View style={localStyles.topTimeTicketContainer}> <View style={localStyles.topTimeTicketContainer}>
{/* Below will be replaced with a copy of SelectCostCenter but for jobs*/} <JobIdSearchSelect
<JobSearchSelect convertedOnly={!currentBodyshop.tt_allow_post_to_invoiced} currentValue={currentSJobId}
notExported={!currentBodyshop.tt_allow_post_to_invoiced} /> onJobSelected={setCurrentSJobId}
convertedOnly={!currentBodyshop.tt_allow_post_to_invoiced}
notExported={!currentBodyshop.tt_allow_post_to_invoiced}
/>
{/* Below will be replaced with a Date Picker*/} {/* Below will be replaced with a Date Picker*/}
{/* <TextInput style={localStyles.input} mode="flat" onChangeText={handleChange("ticketdate")} onBlur={handleBlur("ticketdate")} value={values.ticketdate} label={"Ticket Date"} /> */} {/* <TextInput style={localStyles.input} mode="flat" onChangeText={handleChange("ticketdate")} onBlur={handleBlur("ticketdate")} value={values.ticketdate} label={"Ticket Date"} /> */}
<Button mode="outlined" title="TicketDatePickerButton" onPress={showDatePicker} style={localStyles.dateButton}> <Button
<Text style={localStyles.textForButton}>Ticket Date: {date2.toLocaleDateString()}</Text> mode="outlined"
title="TicketDatePickerButton"
onPress={showDatePicker}
style={localStyles.dateButton}
>
<Text style={localStyles.textForButton}>
Ticket Date: {date2.toLocaleDateString()}
</Text>
</Button> </Button>
<DateTimePickerModal <DateTimePickerModal
isVisible={isDatePickerVisible} isVisible={isDatePickerVisible}
@@ -99,7 +112,12 @@ export function TimeTicketCreate({
label={"Employee"} label={"Employee"}
/> />
<CostCenterSelect currentRatesNCostCenters={currentRatesNCostCenters} currentValue={currentSCC} onValueSelected={setCurrentSCC}/> <CostCenterSelect
currentRatesNCostCenters={currentRatesNCostCenters}
currentValue={currentSCC}
onValueSelected={setCurrentSCC}
/>
<TextInput <TextInput
style={localStyles.inputStyle} style={localStyles.inputStyle}
mode="outlined" mode="outlined"
@@ -149,8 +167,8 @@ const localStyles = StyleSheet.create({
height: 40, height: 40,
justifyContent: "center", justifyContent: "center",
alignContent: "center", alignContent: "center",
borderColor:"blue", borderColor: "blue",
borderWidth:0.8, borderWidth: 0.8,
flex: 1, flex: 1,
}, },
textForButton: { textForButton: {

View File

@@ -49,4 +49,37 @@ export const UPDATE_TIME_TICKET = gql`
} }
} }
} }
`;
export const QUERY_ACTIVE_TIME_TICKETS = gql`
query QUERY_ACTIVE_TIME_TICKETS($employeeId: uuid) {
timetickets(
order_by: { date: desc_nulls_first }
where: {
_and: {
clockoff: { _is_null: true }
employeeid: { _eq: $employeeId }
clockon: { _is_null: false }
jobid: { _is_null: false }
}
}
) {
id
clockon
memo
cost_center
flat_rate
jobid
job {
id
ownr_fn
ownr_ln
ownr_co_nm
v_model_desc
v_make_desc
v_model_yr
ro_number
}
}
}
`; `;

View File

@@ -22,3 +22,7 @@ export const selectGettingRates = createSelector(
[selectEmployee], [selectEmployee],
(employee) => employee.gettingRates (employee) => employee.gettingRates
); );
export const selectTechnician = createSelector(
[selectEmployee],
(employee) => employee?.currentEmployee?.technician
);

24
util/DateFormater.jsx Normal file
View File

@@ -0,0 +1,24 @@
import moment from "moment";
import React from "react";
export function DateFormatter(props) {
return props.children
? moment(props.children).format(
props.includeDay ? "ddd MM/DD/YYYY" : "MM/DD/YYYY"
)
: null;
}
export function DateTimeFormatter(props) {
return props.children
? moment(props.children).format(
props.format ? props.format : "MM/DD/YYYY hh:mm a"
)
: null;
}
export function TimeFormatter(props) {
return props.children
? moment(props.children).format(props.format ? props.format : "hh:mm a")
: null;
}