Skip to content

Commit

Permalink
Merge branch 'develop' into fix-issue-6241
Browse files Browse the repository at this point in the history
  • Loading branch information
GokulramGHV authored Oct 6, 2023
2 parents 6753336 + 9d26e02 commit 1c729c6
Show file tree
Hide file tree
Showing 59 changed files with 1,375 additions and 811 deletions.
Binary file modified cypress/fixtures/sampleAsset.xlsx
Binary file not shown.
2 changes: 1 addition & 1 deletion cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Cypress.Commands.add(

Cypress.Commands.add("verifyNotification", (text) => {
cy.get(".pnotify-container").should("exist").contains(text);
return cy.get(".pnotify-container").click({ force: true });
return cy.get(".pnotify-container").contains(text).click({ force: true });
});

Cypress.on("uncaught:exception", () => {
Expand Down
16 changes: 0 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 13 additions & 5 deletions src/CAREUI/display/RecordMeta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,30 @@ interface Props {
last_name: string;
last_login: string | undefined;
};
inlineUser?: boolean;
}

/**
* A generic component to display relative time along with a tooltip and a user
* if provided.
*/
const RecordMeta = ({ time, user, prefix, className }: Props) => {
const RecordMeta = ({ time, user, prefix, className, inlineUser }: Props) => {
const isOnline = user && isUserOnline(user);

let child = (
<div className="tooltip">
<span className="underline">{relativeTime(time)}</span>
<span className="tooltip-text tooltip-bottom flex -translate-x-1/2 gap-1 text-xs font-medium tracking-wider">
{formatDateTime(time)}
{user && (
<>
{user && !inlineUser && (
<span className="flex items-center gap-1">
by
<CareIcon className="care-l-user" />
{user.first_name} {user.last_name}
{isOnline && (
<div className="h-1 w-1 rounded-full bg-primary-500" />
<div className="h-1.5 w-1.5 rounded-full bg-primary-400" />
)}
</>
</span>
)}
</span>
</div>
Expand All @@ -43,7 +45,13 @@ const RecordMeta = ({ time, user, prefix, className }: Props) => {
<div className="flex items-center gap-1">
{prefix}
{child}
{user && inlineUser && <span>by</span>}
{user && <CareIcon className="care-l-user" />}
{user && inlineUser && (
<span className="font-medium">
{user.first_name} {user.last_name}
</span>
)}
</div>
);
}
Expand Down
45 changes: 33 additions & 12 deletions src/Common/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,7 @@ export const XLSXAssetImportSchema = {
Class: {
prop: "asset_class",
type: String,
oneOf: ["HL7MONITOR", "ONVIF"],
oneOf: ["HL7MONITOR", "ONVIF", "VENTILATOR", ""],
},
Description: { prop: "description", type: String },
"Working Status": {
Expand All @@ -908,7 +908,7 @@ export const XLSXAssetImportSchema = {
} else if (status === "NOT WORKING") {
return false;
} else {
throw new Error("Invalid Working Status");
throw new Error("Invalid Working Status: " + status);
}
},
required: true,
Expand All @@ -917,6 +917,7 @@ export const XLSXAssetImportSchema = {
prop: "not_working_reason",
type: String,
},
"Serial Number": { prop: "serial_number", type: String },
"QR Code ID": { prop: "qr_code_id", type: String },
Manufacturer: { prop: "manufacturer", type: String },
"Vendor Name": { prop: "vendor_name", type: String },
Expand All @@ -925,10 +926,11 @@ export const XLSXAssetImportSchema = {
prop: "support_email",
type: String,
parse: (email: string) => {
if (!email) return null;
const isValid = /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/.test(email);

if (!isValid) {
throw new Error("Invalid Support Email");
throw new Error("Invalid Support Email: " + email);
}

return email;
Expand All @@ -938,23 +940,38 @@ export const XLSXAssetImportSchema = {
prop: "support_phone",
type: String,
parse: (phone: number | string) => {
phone = "+91" + String(phone);
if (!PhoneNumberValidator(["support"])(phone) === undefined) {
throw new Error("Invalid Support Phone Number");
phone = String(phone);
if (phone.length === 10 && !phone.startsWith("1800")) {
phone = "+91" + phone;
}
if (phone.startsWith("91") && phone.length === 12) {
phone = "+" + phone;
}
if (phone.startsWith("+911800")) {
phone = "1800" + phone.slice(6);
}
if (
PhoneNumberValidator(["mobile", "landline", "support"])(phone) !==
undefined
) {
throw new Error("Invalid Support Phone Number: " + phone);
}

return phone ? phone : undefined;
},
required: true,
},
"Warrenty End Date": {
"Warranty End Date": {
prop: "warranty_amc_end_of_validity",
type: String,
parse: (date: string) => {
const parsed = new Date(date);
if (!date) return null;
const parts = date.split("-");
const reformattedDateStr = `${parts[2]}-${parts[1]}-${parts[0]}`;
const parsed = new Date(reformattedDateStr);

if (String(parsed) === "Invalid Date") {
throw new Error("Invalid Warrenty End Date");
throw new Error("Invalid Warranty End Date:" + date);
}

return dateQueryString(parsed);
Expand All @@ -964,10 +981,13 @@ export const XLSXAssetImportSchema = {
prop: "last_serviced_on",
type: String,
parse: (date: string) => {
const parsed = new Date(date);
if (!date) return null;
const parts = date.split("-");
const reformattedDateStr = `${parts[2]}-${parts[1]}-${parts[0]}`;
const parsed = new Date(reformattedDateStr);

if (String(parsed) === "Invalid Date") {
throw new Error("Invalid Last Service Date");
throw new Error("Invalid Last Service Date:" + date);
}

return dateQueryString(parsed);
Expand All @@ -981,13 +1001,14 @@ export const XLSXAssetImportSchema = {
prop: "local_ip_address",
type: String,
parse: (ip: string) => {
if (!ip) return null;
const isValid =
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(
ip
);

if (!isValid) {
throw new Error("Invalid Config IP Address");
throw new Error("Invalid Config IP Address: " + ip);
}

return ip;
Expand Down
32 changes: 12 additions & 20 deletions src/Common/hooks/useRangePagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,17 @@ interface Props {
bounds: DateRange;
perPage: number;
slots?: number;
snapToLatest?: boolean;
reverse?: boolean;
defaultEnd?: boolean;
}

const useRangePagination = ({ bounds, perPage, ...props }: Props) => {
const [currentRange, setCurrentRange] = useState(
getInitialBounds(bounds, perPage, props.snapToLatest)
getInitialBounds(bounds, perPage, props.defaultEnd)
);

useEffect(() => {
setCurrentRange(getInitialBounds(bounds, perPage, props.snapToLatest));
}, [bounds, perPage, props.snapToLatest]);
setCurrentRange(getInitialBounds(bounds, perPage, props.defaultEnd));
}, [bounds, perPage, props.defaultEnd]);

const next = () => {
const { end } = currentRange;
Expand Down Expand Up @@ -63,24 +62,17 @@ const useRangePagination = ({ bounds, perPage, ...props }: Props) => {
}

const slots: DateRange[] = [];
const { start, end } = currentRange;
const { start } = currentRange;
const delta = perPage / props.slots;

for (let i = 0; i < props.slots; i++) {
if (props.snapToLatest) {
slots.push({
start: new Date(end.valueOf() - delta * (i - 1)),
end: new Date(end.valueOf() - delta * i),
});
} else {
slots.push({
start: new Date(start.valueOf() + delta * i),
end: new Date(start.valueOf() + delta * (i + 1)),
});
}
slots.push({
start: new Date(start.valueOf() + delta * i),
end: new Date(start.valueOf() + delta * (i + 1)),
});
}

return props.reverse ? slots.reverse() : slots;
return slots;
}, [currentRange, props.slots, perPage]);

return {
Expand All @@ -98,15 +90,15 @@ export default useRangePagination;
const getInitialBounds = (
bounds: DateRange,
perPage: number,
snapToLatest?: boolean
defaultEnd?: boolean
) => {
const deltaBounds = bounds.end.valueOf() - bounds.start.valueOf();

if (deltaBounds < perPage) {
return bounds;
}

if (snapToLatest) {
if (defaultEnd) {
return {
start: new Date(bounds.end.valueOf() - perPage),
end: bounds.end,
Expand Down
45 changes: 45 additions & 0 deletions src/Common/hooks/useSlug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { usePath } from "raviger";

/**
* Returns the slug from the current path.
* @param prefix The prefix of the slug.
* @returns The slug.
* @example
* // Current path: /consultation/94b9a
* const consultation = useSlug("consultation"); // consultation = "94b9a"
*/
export default function useSlug(prefix: string) {
const path = usePath() ?? "";
return findSlug(path.split("/"), prefix);
}

/**
* Returns the slugs from the current path.
* @param prefix The prefixes of the slug.
* @returns The slugs
* @example
* // Current path: /facility/5b0a/consultation/94b9a
* const [facility, consultation] = useSlug("facility", "consultation");
* // facility = "5b0a"
* // consultation = "94b9a"
*/
export const useSlugs = (...prefix: string[]) => {
const path = usePath() ?? "";
return prefix.map((p) => findSlug(path.split("/"), p));
};

const findSlug = (segments: string[], prefix: string) => {
const index = segments.findIndex((segment) => segment === prefix);
if (index === -1) {
throw new Error(
`Prefix "${prefix}" not found in path "${segments.join("/")}"`
);
}

const slug = segments[index + 1];
if (!slug) {
throw new Error(`Slug not found in path "${segments.join("/")}"`);
}

return slug;
};
Loading

0 comments on commit 1c729c6

Please sign in to comment.