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