Compare commits
8 Commits
4a0fe47000
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
6413ce0b9b
|
|||
|
ffda5c6a61
|
|||
|
37ada2d8f5
|
|||
|
ff04bb36de
|
|||
|
16f044d308
|
|||
|
b6949a7673
|
|||
|
44932cf3e2
|
|||
|
ef2846f626
|
@@ -3,20 +3,21 @@ type: docker
|
||||
name: Demo Deploy Pipeline
|
||||
|
||||
workspace:
|
||||
path: /drone/bopeep
|
||||
path: /drone/walden
|
||||
|
||||
steps:
|
||||
- name: Deploy Container
|
||||
image: docker
|
||||
privileged: true
|
||||
commands:
|
||||
- docker compose -f docker-compose.prod.yml build --pull --no-cache
|
||||
- docker compose -f docker-compose.prod.yml build
|
||||
# - docker compose -f docker-compose.prod.yml build --pull --no-cache
|
||||
- docker compose -f docker-compose.prod.yml up --remove-orphans --force-recreate --wait
|
||||
volumes:
|
||||
- name: dockersock
|
||||
path: /var/run/docker.sock
|
||||
- name: dockerconfig
|
||||
path: /drone/bopeep/.docker/config.json
|
||||
path: /drone/walden/.docker/config.json
|
||||
- name: Send Status Notifications
|
||||
image: plugins/webhook
|
||||
privileged: true
|
||||
|
||||
@@ -12,8 +12,8 @@ services:
|
||||
networks:
|
||||
- walden-backend
|
||||
volumes:
|
||||
- 'db:/data/db'
|
||||
- 'db:/data/configdb'
|
||||
- 'walden-db:/data/db'
|
||||
- 'walden-db:/data/configdb'
|
||||
restart: unless-stopped
|
||||
|
||||
frontend:
|
||||
@@ -26,16 +26,16 @@ services:
|
||||
- NODE_ENV=production
|
||||
- MONGO_URL=mongodb://mongo:27017/bopeep
|
||||
ports:
|
||||
- 3000:3000
|
||||
- 3003:3000
|
||||
labels:
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=docknet'
|
||||
- 'traefik.http.routers.labs-bopeep.rule=Host(`area51.mifi.dev`)'
|
||||
- 'traefik.http.routers.labs-bopeep.entrypoints=websecure'
|
||||
- 'traefik.http.routers.labs-bopeep.tls=true'
|
||||
- 'traefik.http.routers.labs-bopeep.tls.certresolver=letsencrypt'
|
||||
- 'traefik.http.routers.labs-bopeep.service=labs-bopeep-service'
|
||||
- 'traefik.http.services.labs-bopeep-service.loadbalancer.server.port=3000'
|
||||
- 'traefik.http.routers.labs-walden.rule=Host(`area51.mifi.dev`)'
|
||||
- 'traefik.http.routers.labs-walden.entrypoints=websecure'
|
||||
- 'traefik.http.routers.labs-walden.tls=true'
|
||||
- 'traefik.http.routers.labs-walden.tls.certresolver=letsencrypt'
|
||||
- 'traefik.http.routers.labs-walden.service=labs-walden-service'
|
||||
- 'traefik.http.services.labs-walden-service.loadbalancer.server.port=3000'
|
||||
networks:
|
||||
- walden-backend
|
||||
- docknet
|
||||
@@ -49,5 +49,5 @@ networks:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
db:
|
||||
external: false
|
||||
walden-db:
|
||||
external: true
|
||||
|
||||
@@ -18,29 +18,29 @@ export function Bins() {
|
||||
switch (event.key) {
|
||||
case 'ArrowDown':
|
||||
event.preventDefault();
|
||||
setBin(Bin.LOSS);
|
||||
!!item && setBin(Bin.LOSS);
|
||||
break;
|
||||
case 'ArrowLeft':
|
||||
event.preventDefault();
|
||||
setBin(Bin.PROCESS);
|
||||
!!item && setBin(Bin.PROCESS);
|
||||
break;
|
||||
case 'ArrowRight':
|
||||
event.preventDefault();
|
||||
setBin(Bin.SHOULDER_TAP);
|
||||
!!item && setBin(Bin.SHOULDER_TAP);
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
event.preventDefault();
|
||||
setBin(Bin.DONATE);
|
||||
!!item && setBin(Bin.DONATE);
|
||||
break;
|
||||
}
|
||||
}, [bin, item, setBin, setItem]);
|
||||
}, [item, setBin]);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('keydown', handleKeydown);
|
||||
return () => {
|
||||
window.removeEventListener('keydown', handleKeydown);
|
||||
};
|
||||
}, []);
|
||||
}, [handleKeydown]);
|
||||
|
||||
return (
|
||||
<div className={styles.bins}>
|
||||
|
||||
@@ -15,7 +15,6 @@ export function ProductInfo() {
|
||||
const { item, setItem } = useContext(BinnerContext);
|
||||
const { processors } = useContext(SupplyChainContext);
|
||||
const [inputItem, setInputItem] = useState<Partial<ParsedBarcode> | null>(null);
|
||||
const dateRef = useRef<HTMLInputElement>(null);
|
||||
const weightRef = useRef<HTMLInputElement>(null);
|
||||
const getProcessorByBarcodeId = useGetProcessorByBarcodeId();
|
||||
|
||||
@@ -32,8 +31,22 @@ export function ProductInfo() {
|
||||
setItem(barcodeToProduct(`${inputItem?.product}${inputItem?.date}${inputItem?.processor}${inputItem?.weight}`));
|
||||
setInputItem(null);
|
||||
}
|
||||
setIsEntryMode(!isCompleteItem(inputItem));
|
||||
}, [inputItem])
|
||||
}, [inputItem]);
|
||||
|
||||
const getDateString = (date: Date) => {
|
||||
const yyyy = date.getFullYear();
|
||||
let mm: number | string = date.getMonth() + 1;
|
||||
let dd: number | string = date.getDate();
|
||||
|
||||
if (dd < 10) {
|
||||
dd = '0' + dd;
|
||||
}
|
||||
|
||||
if (mm < 10) {
|
||||
mm = '0' + mm;
|
||||
}
|
||||
return `${yyyy}-${mm}-${dd}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.productInfo}>
|
||||
@@ -58,13 +71,13 @@ export function ProductInfo() {
|
||||
<div className={styles.card}>
|
||||
<label htmlFor="date">Packaged Date</label>
|
||||
<input
|
||||
id="date" value={!!item ? ordinalToDate(item.date).toDateString() : ''}
|
||||
id="date"
|
||||
type="date"
|
||||
value={!!item ? getDateString(ordinalToDate(item.date)) : undefined}
|
||||
contentEditable={isEntryMode}
|
||||
ref={dateRef}
|
||||
onChange={(e) => {
|
||||
dateRef.current.value = e.currentTarget.value;
|
||||
setInputItem({ ...inputItem || {}, date: dateToOrdinal(new Date(e.currentTarget.value)) })
|
||||
}}
|
||||
onChange={isEntryMode ? (e) => {
|
||||
setInputItem({ ...inputItem || {}, date: `${dateToOrdinal(new Date(e.currentTarget.valueAsNumber))}` })
|
||||
} : undefined}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.card}>
|
||||
@@ -86,26 +99,36 @@ export function ProductInfo() {
|
||||
</div>
|
||||
<div className={styles.card}>
|
||||
<label htmlFor="weight">Weight</label>
|
||||
<div className={styles.inputWithButton}>
|
||||
<input
|
||||
id="weight"
|
||||
value={!!item ? `${item.weight} lbs.` : ''}
|
||||
contentEditable={false}
|
||||
tabIndex={-1}
|
||||
ref={weightRef}
|
||||
/>
|
||||
{isEntryMode && (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
const weight = faker.number.int({ min: 1000, max: 1999 });
|
||||
weightRef.current.value = `${weight / 100} lbs`; setInputItem({ ...inputItem || {}, weight })
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
Weight from Scale
|
||||
</button>
|
||||
{isEntryMode ? (
|
||||
<div className={styles.inputWithButton}>
|
||||
<input
|
||||
id="weight"
|
||||
contentEditable={false}
|
||||
tabIndex={-1}
|
||||
ref={weightRef}
|
||||
/>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
const weight = faker.number.int({ min: 1000, max: 1999 });
|
||||
if (weightRef.current) {
|
||||
weightRef.current.value = `${weight / 100} lbs`;
|
||||
}
|
||||
setInputItem({ ...inputItem || {}, weight })
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
Weight from Scale
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<input
|
||||
id="weight"
|
||||
value={!!item ? `${item?.weight} lbs.` : ''}
|
||||
contentEditable={false}
|
||||
tabIndex={-1}
|
||||
readOnly
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -22,17 +22,21 @@ export default function Page() {
|
||||
break;
|
||||
case 'Escape':
|
||||
event.preventDefault();
|
||||
setBin(null);
|
||||
if (bin !== null) {
|
||||
setBin(null);
|
||||
} else {
|
||||
setItem(null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}, [bin, item, setBin, setItem]);
|
||||
}, [bin, setBin, setItem]);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('keydown', handleKeydown);
|
||||
return () => {
|
||||
window.removeEventListener('keydown', handleKeydown);
|
||||
};
|
||||
}, []);
|
||||
}, [handleKeydown]);
|
||||
|
||||
return (
|
||||
<main className={styles.page}>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
.page {
|
||||
padding: 1rem;
|
||||
min-height: 100vh;
|
||||
|
||||
h1 {
|
||||
margin-bottom: 1em;
|
||||
|
||||
@@ -48,11 +48,9 @@ export default function Page() {
|
||||
onDrop={handleDrop}
|
||||
>
|
||||
<h2>{binToLabel(parseInt(k))}</h2>
|
||||
{v.length > 0 && (
|
||||
<ul onDrop={handleDrop}>
|
||||
{v.map((item) => (<li key={(item as BinnedDocument)._id} onDragStart={() => setDragging(item)} draggable>{`${item.product} - ${item.weight}lbs`}</li>))}
|
||||
</ul>
|
||||
)}
|
||||
<ul onDrop={handleDrop}>
|
||||
{v.length > 0 && v.map((item) => (<li key={(item as BinnedDocument)._id} onDragStart={() => setDragging(item)} draggable>{`${item.product} - ${item.weight}lbs`}</li>))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,6 @@ import { faker } from '@faker-js/faker';
|
||||
|
||||
import { Product } from "./product.enum";
|
||||
import { dateToOrdinal } from './ordinalDate';
|
||||
import { ValueOf } from 'next/dist/shared/lib/constants';
|
||||
|
||||
export type Barcode = string;
|
||||
|
||||
|
||||
@@ -16,14 +16,15 @@ export async function addToBin(bin: number, item: Omit<BinItem, 'bin'>) {
|
||||
|
||||
export async function getBinsContents(): Promise<BinsContents> {
|
||||
await db();
|
||||
const bins = {} as BinsContents;
|
||||
const createdAt = new Date();
|
||||
createdAt.setUTCHours(0,0,0,0);
|
||||
|
||||
createdAt.setDate(createdAt.getDate() - 1);
|
||||
createdAt.setHours(0,0,0,0);
|
||||
// Should be today, but lets do yesterday so there is more to see for demo purposes
|
||||
const binned = await Binned.find({ createdAt: { $gte: createdAt }});
|
||||
binned.forEach((item: BinItem) => bins[item.bin] = [...(bins[item.bin] ?? []), item]);
|
||||
return JSON.parse(JSON.stringify(bins));
|
||||
return JSON.parse(JSON.stringify(binned.reduce((bins: { [key in Bin]: BinItem[] }, cur: BinItem) => {
|
||||
bins[cur.bin] = [...bins[cur.bin], cur];
|
||||
return bins;
|
||||
}, { [Bin.LOSS]: [], [Bin.PROCESS]: [], [Bin.DONATE]: [], [Bin.SHOULDER_TAP]: [] })));
|
||||
}
|
||||
|
||||
export async function switchBin(bin: number, id: StringSchemaDefinition) {
|
||||
|
||||
Reference in New Issue
Block a user