Merged in feature/IO-3020-IO-3036-imex-lite-rome-lite (pull request #2012)

feature/IO-3020-IO-3036-imex-lite-rome-lite

Approved-by: Patrick Fic
This commit is contained in:
Patrick Fic
2024-12-11 17:45:25 +00:00
8 changed files with 258 additions and 142 deletions

79
.gitattributes vendored
View File

@@ -1 +1,80 @@
# Ensure all text files use LF for line endings
* text eol=lf * text eol=lf
# Binary files should not be modified by Git
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.webp binary
*.svg binary
# Fonts
*.woff binary
*.woff2 binary
*.ttf binary
*.otf binary
*.eot binary
# Videos
*.mp4 binary
*.mov binary
*.avi binary
*.mkv binary
*.webm binary
# Audio
*.mp3 binary
*.wav binary
*.ogg binary
*.flac binary
# Archives and compressed files
*.zip binary
*.gz binary
*.tar binary
*.7z binary
*.rar binary
# PDF and documents
*.pdf binary
*.doc binary
*.docx binary
*.xls binary
*.xlsx binary
*.ppt binary
*.pptx binary
# Exclude JSON and other data files from text processing, if necessary
*.json text
*.xml text
*.csv text
# Scripts and code files should maintain LF endings
*.js text eol=lf
*.jsx text eol=lf
*.ts text eol=lf
*.tsx text eol=lf
*.css text eol=lf
*.scss text eol=lf
*.html text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.md text eol=lf
*.sh text eol=lf
*.py text eol=lf
*.rb text eol=lf
*.java text eol=lf
*.php text eol=lf
# Git configuration files
.gitattributes text eol=lf
.gitignore text eol=lf
*.gitattributes text eol=lf
# Exclude some other potential binary files
*.db binary
*.sqlite binary
*.exe binary
*.dll binary

View File

@@ -47,7 +47,7 @@ export function JobDetailCards({ bodyshop, setPrintCenterContext }) {
md: "100%", md: "100%",
lg: "75%", lg: "75%",
xl: "75%", xl: "75%",
xxl: "60%" xxl: "75%"
}; };
const drawerPercentage = selectedBreakpoint ? bpoints[selectedBreakpoint[0]] : "100%"; const drawerPercentage = selectedBreakpoint ? bpoints[selectedBreakpoint[0]] : "100%";

View File

@@ -3,6 +3,7 @@ import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { GenerateThumbUrl } from "../jobs-documents-gallery/job-documents.utility"; import { GenerateThumbUrl } from "../jobs-documents-gallery/job-documents.utility";
import CardTemplate from "./job-detail-cards.template.component"; import CardTemplate from "./job-detail-cards.template.component";
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";
export default function JobDetailCardsDocumentsComponent({ loading, data }) { export default function JobDetailCardsDocumentsComponent({ loading, data }) {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -20,6 +21,7 @@ export default function JobDetailCardsDocumentsComponent({ loading, data }) {
title={t("jobs.labels.cards.documents")} title={t("jobs.labels.cards.documents")}
extraLink={`/manage/jobs/${data.id}?tab=documents`} extraLink={`/manage/jobs/${data.id}?tab=documents`}
> >
<UpsellComponent disableMask upsell={upsellEnum().media.general}>
{data.documents.length > 0 ? ( {data.documents.length > 0 ? (
<Carousel autoplay> <Carousel autoplay>
{data.documents.map((item) => ( {data.documents.map((item) => (
@@ -29,6 +31,7 @@ export default function JobDetailCardsDocumentsComponent({ loading, data }) {
) : ( ) : (
<div>{t("documents.errors.nodocuments")}</div> <div>{t("documents.errors.nodocuments")}</div>
)} )}
</UpsellComponent>
</CardTemplate> </CardTemplate>
); );
} }

View File

@@ -892,10 +892,10 @@ export function JobsDetailHeaderActions({
key: "postbills", key: "postbills",
id: "job-actions-postbills", id: "job-actions-postbills",
disabled: !job.converted, disabled: !job.converted,
label: <LockerWrapperComponent featureName="bill">{t("jobs.actions.postbills")}</LockerWrapperComponent>, label: <LockerWrapperComponent featureName="bills">{t("jobs.actions.postbills")}</LockerWrapperComponent>,
onClick: () => { onClick: () => {
logImEXEvent("job_header_enter_bills"); logImEXEvent("job_header_enter_bills");
HasFeatureAccess({ featureName: "bills", bodyshop }) &&
setBillEnterContext({ setBillEnterContext({
actions: { refetch: refetch }, actions: { refetch: refetch },
context: { context: {

View File

@@ -133,7 +133,7 @@ function JobsDocumentsComponent({
{!hasMediaAccess && ( {!hasMediaAccess && (
<Col span={24}> <Col span={24}>
<Card> <Card>
<UpsellComponent upsell={upsellEnum().media.general} /> <UpsellComponent disableMask upsell={upsellEnum().media.general} />
</Card> </Card>
</Col> </Col>
)} )}

View File

@@ -1,5 +1,5 @@
import { FileExcelFilled, SyncOutlined } from "@ant-design/icons"; import { FileExcelFilled, SyncOutlined } from "@ant-design/icons";
import { Alert, Button, Card, Space } from "antd"; import { Alert, Button, Card, Col, Row, Space } from "antd";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { Gallery } from "react-grid-gallery"; import { Gallery } from "react-grid-gallery";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -18,6 +18,7 @@ import JobsDocumentsLocalGallerySelectAllComponent from "./jobs-documents-local-
import Lightbox from "react-image-lightbox"; import Lightbox from "react-image-lightbox";
import "react-image-lightbox/style.css"; import "react-image-lightbox/style.css";
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component"; import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
@@ -88,6 +89,8 @@ export function JobsDocumentsLocalGallery({
const hasMediaAccess = HasFeatureAccess({ bodyshop, featureName: "media" }); const hasMediaAccess = HasFeatureAccess({ bodyshop, featureName: "media" });
return ( return (
<div> <div>
<Row gutter={[16, 16]}>
<Col span={24}>
<Space wrap> <Space wrap>
<Button <Button
onClick={() => { onClick={() => {
@@ -110,9 +113,25 @@ export function JobsDocumentsLocalGallery({
<JobsLocalGalleryDownloadButton job={job} /> <JobsLocalGalleryDownloadButton job={job} />
<JobsDocumentsLocalDeleteButton jobid={job.id} /> <JobsDocumentsLocalDeleteButton jobid={job.id} />
</Space> </Space>
</Col>
{!hasMediaAccess && (
<Col span={24}>
<Card> <Card>
<DocumentsLocalUploadComponent job={job} invoice_number={invoice_number} vendorid={vendorid} allowAllTypes /> <UpsellComponent disableMask upsell={upsellEnum().media.general} />
</Card> </Card>
</Col>
)}
<Col span={24}>
<Card>
<DocumentsLocalUploadComponent
job={job}
invoice_number={invoice_number}
vendorid={vendorid}
allowAllTypes
/>
</Card>
</Col>
<Col span={24}>
<Card title={t("jobs.labels.documents-images")}> <Card title={t("jobs.labels.documents-images")}>
<Gallery <Gallery
images={jobMedia.images} images={jobMedia.images}
@@ -138,6 +157,8 @@ export function JobsDocumentsLocalGallery({
}} }}
/> />
</Card> </Card>
</Col>
<Col span={24}>
<Card title={t("jobs.labels.documents-other")}> <Card title={t("jobs.labels.documents-other")}>
<Gallery <Gallery
images={jobMedia.other} images={jobMedia.other}
@@ -157,6 +178,7 @@ export function JobsDocumentsLocalGallery({
}} }}
/> />
</Card> </Card>
</Col>
{modalState.open && ( {modalState.open && (
<Lightbox <Lightbox
mainSrc={jobMedia.images[modalState.index].fullsize} mainSrc={jobMedia.images[modalState.index].fullsize}
@@ -177,6 +199,7 @@ export function JobsDocumentsLocalGallery({
} }
/> />
)} )}
</Row>
</div> </div>
); );
} }

View File

@@ -1,4 +1,4 @@
import { Alert, Form, InputNumber, Switch } from "antd"; import { Alert, Form, Switch } from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import LayoutFormRow from "../layout-form-row/layout-form-row.component"; import LayoutFormRow from "../layout-form-row/layout-form-row.component";

View File

@@ -1,5 +1,5 @@
import { useQuery } from "@apollo/client"; import { useQuery } from "@apollo/client";
import { Col, Row, Typography } from "antd"; import { Card, Col, Row, Typography } from "antd";
import dayjs from "../../utils/day"; import dayjs from "../../utils/day";
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -14,6 +14,8 @@ import { QUERY_JOB_CHECKLISTS } from "../../graphql/jobs.queries";
import { setBreadcrumbs, setSelectedHeader } from "../../redux/application/application.actions"; import { setBreadcrumbs, setSelectedHeader } from "../../redux/application/application.actions";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import InstanceRenderManager from "../../utils/instanceRenderMgr"; import InstanceRenderManager from "../../utils/instanceRenderMgr";
import FeatureWrapperComponent from "../../components/feature-wrapper/feature-wrapper.component";
import UpsellComponent, { upsellEnum } from "../../components/upsell/upsell.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser //currentUser: selectCurrentUser
@@ -73,6 +75,14 @@ export function JobsChecklistViewContainer({ bodyshop, setBreadcrumbs, setSelect
); );
return ( return (
<FeatureWrapperComponent
featureName="checklist"
noauth={
<Card>
<UpsellComponent upsell={upsellEnum().checklist.general} />
</Card>
}
>
<RbacWrapper action="jobs:checklist-view"> <RbacWrapper action="jobs:checklist-view">
<Row gutter={[16, 16]}> <Row gutter={[16, 16]}>
<Col span={12}> <Col span={12}>
@@ -105,6 +115,7 @@ export function JobsChecklistViewContainer({ bodyshop, setBreadcrumbs, setSelect
</Col> </Col>
</Row> </Row>
</RbacWrapper> </RbacWrapper>
</FeatureWrapperComponent>
); );
} }