Compare commits

...

8 Commits

Author SHA1 Message Date
6413ce0b9b Goodbye extraneous console logging...
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-24 20:05:59 -05:00
ffda5c6a61 ...
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-24 18:53:19 -05:00
37ada2d8f5 ...
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-24 18:47:48 -05:00
ff04bb36de Take that, Traefik!
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-24 18:39:23 -05:00
16f044d308 Motherfu...
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-24 18:06:46 -05:00
b6949a7673 Update CI/CD pipeline
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-24 17:37:36 -05:00
44932cf3e2 How was it working and then broken? I really hate Traefik somethimes...
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-24 17:28:22 -05:00
ef2846f626 Fixes for a few oddities and the Traefik issues
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-24 17:18:42 -05:00
9 changed files with 89 additions and 62 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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}>

View File

@@ -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>

View File

@@ -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}>

View File

@@ -2,6 +2,7 @@
.page {
padding: 1rem;
min-height: 100vh;
h1 {
margin-bottom: 1em;

View File

@@ -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>

View File

@@ -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;

View File

@@ -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) {