handy 1 месяц назад
Родитель
Сommit
fab5ef1cfa
1 измененных файлов с 96 добавлено и 5 удалено
  1. 96 5
      src/components/warehouse-layout-enhancers.ts

+ 96 - 5
src/components/warehouse-layout-enhancers.ts

@@ -24,9 +24,20 @@ interface LocalColumnAisleRule extends RowScopedRule {
 
 interface LocalColumnShiftRule extends RowScopedRule {
   startColumn: number
+  endColumn?: number
   shiftCols: number
 }
 
+interface ManualColumnOffsetRule extends RowScopedRule {
+  startColumn: number
+  endColumn?: number
+  offsetCols: number
+}
+
+interface ColumnCompactionRule extends RowScopedRule {
+  startColumn: number
+}
+
 interface GlobalColumnAisleRule {
   breakpoint: number
   excludeRows?: readonly number[]
@@ -38,6 +49,8 @@ interface WarehouseLayoutRuleSet {
   globalColumnAisles: readonly GlobalColumnAisleRule[]
   localColumnAisles: readonly LocalColumnAisleRule[]
   localColumnShifts: readonly LocalColumnShiftRule[]
+  manualColumnOffsets: readonly ManualColumnOffsetRule[]
+  columnCompactions: readonly ColumnCompactionRule[]
 }
 
 const scopedRows = <T extends object>(rows: readonly number[], rule: T): T & Pick<RowScopedRule, 'rows'> => ({
@@ -114,6 +127,10 @@ const FIRST_FLOOR_LOCAL_COLUMN_SHIFTS = [
     startColumn: 0,
     shiftCols: 1
   }),
+  scopedRows([8, 11], {
+    startColumn: 8,
+    shiftCols: 1
+  }),
   scopedRows([6, 13], {
     startColumn: 5,
     shiftCols: 1
@@ -132,11 +149,32 @@ const FIRST_FLOOR_LOCAL_COLUMN_SHIFTS = [
   })
 ] as const
 
+const FIRST_FLOOR_MANUAL_COLUMN_OFFSETS = [
+  scopedRows([8, 11], {
+    startColumn: 13,
+    endColumn: 17,
+    offsetCols: -1
+  }),
+  scopedRows([8, 11], {
+    startColumn: 18,
+    endColumn: 18,
+    offsetCols: -1
+  })
+] as const
+
+const FIRST_FLOOR_COLUMN_COMPACTIONS = [
+  scopedRows([9, 10], {
+    startColumn: 11
+  })
+] as const
+
 const FIRST_FLOOR_RULE_SET: WarehouseLayoutRuleSet = {
   rowAisleBreakpoints: FIRST_FLOOR_ROW_AISLE_BREAKPOINTS,
   globalColumnAisles: FIRST_FLOOR_GLOBAL_COLUMN_AISLES,
   localColumnAisles: FIRST_FLOOR_LOCAL_COLUMN_AISLES,
-  localColumnShifts: FIRST_FLOOR_LOCAL_COLUMN_SHIFTS
+  localColumnShifts: FIRST_FLOOR_LOCAL_COLUMN_SHIFTS,
+  manualColumnOffsets: FIRST_FLOOR_MANUAL_COLUMN_OFFSETS,
+  columnCompactions: FIRST_FLOOR_COLUMN_COMPACTIONS
 }
 
 const RULE_SETS_BY_LEVEL: Readonly<Record<number, WarehouseLayoutRuleSet>> = {
@@ -193,21 +231,39 @@ const sumLocalColumnShiftOffsets = (
   rules: readonly LocalColumnShiftRule[]
 ) =>
   rules.reduce((total, rule) => {
-    if (matchesRowScope(parsedLocation.y, rule) && parsedLocation.x >= rule.startColumn) {
+    const matchedColumn = parsedLocation.x >= rule.startColumn
+      && (rule.endColumn === undefined || parsedLocation.x <= rule.endColumn)
+
+    if (matchesRowScope(parsedLocation.y, rule) && matchedColumn) {
       return total + rule.shiftCols
     }
 
     return total
   }, 0)
 
-const applyRuleSet = (
-  currentPosition: WarehouseLayoutPosition,
+const sumManualColumnOffsets = (
+  parsedLocation: WarehouseLayoutParsedLocation,
+  rules: readonly ManualColumnOffsetRule[]
+) =>
+  rules.reduce((total, rule) => {
+    const matchedColumn = parsedLocation.x >= rule.startColumn
+      && (rule.endColumn === undefined || parsedLocation.x <= rule.endColumn)
+
+    if (matchesRowScope(parsedLocation.y, rule) && matchedColumn) {
+      return total + rule.offsetCols
+    }
+
+    return total
+  }, 0)
+
+const getBaseGridColOffset = (
   parsedLocation: WarehouseLayoutParsedLocation,
   ruleSet: WarehouseLayoutRuleSet
 ) => {
   const columnShiftCount = sumLocalColumnShiftOffsets(parsedLocation, ruleSet.localColumnShifts)
   const effectiveColumn = parsedLocation.x + columnShiftCount
-  const gridColOffset =
+
+  return (
     columnShiftCount +
     sumGlobalColumnAisleOffsets(
       parsedLocation.y,
@@ -215,6 +271,41 @@ const applyRuleSet = (
       ruleSet.globalColumnAisles
     ) +
     sumLocalColumnAisleOffsets(parsedLocation.y, effectiveColumn, ruleSet.localColumnAisles)
+  )
+}
+
+const sumColumnCompactionOffsets = (
+  parsedLocation: WarehouseLayoutParsedLocation,
+  ruleSet: WarehouseLayoutRuleSet
+) =>
+  ruleSet.columnCompactions.reduce((total, rule) => {
+    if (!matchesRowScope(parsedLocation.y, rule) || parsedLocation.x < rule.startColumn) {
+      return total
+    }
+
+    if (parsedLocation.x === rule.startColumn) {
+      return total - 1
+    }
+
+    const previousLocation: WarehouseLayoutParsedLocation = {
+      ...parsedLocation,
+      x: parsedLocation.x - 1
+    }
+    const previousGridCol = previousLocation.x + getBaseGridColOffset(previousLocation, ruleSet)
+    const currentGridCol = parsedLocation.x + getBaseGridColOffset(parsedLocation, ruleSet)
+
+    return total + (previousGridCol - currentGridCol)
+  }, 0)
+
+const applyRuleSet = (
+  currentPosition: WarehouseLayoutPosition,
+  parsedLocation: WarehouseLayoutParsedLocation,
+  ruleSet: WarehouseLayoutRuleSet
+) => {
+  const gridColOffset =
+    getBaseGridColOffset(parsedLocation, ruleSet) +
+    sumManualColumnOffsets(parsedLocation, ruleSet.manualColumnOffsets) +
+    sumColumnCompactionOffsets(parsedLocation, ruleSet)
   const gridRowOffset = sumRowAisleOffsets(parsedLocation.y, ruleSet.rowAisleBreakpoints)
 
   return {