Jelajahi Sumber

feat(web-admin): add mp plan detail action splitter.

Cap the sticky footer at two primary actions and park the rest in a more sheet.

Co-authored-by: Cursor <cursoragent@cursor.com>
wuzilong 1 bulan lalu
induk
melakukan
92bb4bf0d0

+ 63 - 0
web-admin/scripts/check-mp-pl-plan-detail-actions.mjs

@@ -0,0 +1,63 @@
+/**
+ * Mirrors web-admin/src/utils/mp-pl-plan-detail-actions.ts (no vitest in web-admin).
+ */
+function splitMpPlanDetailActions(input) {
+  const primary = []
+  const more = []
+
+  if (input.canEdit) primary.push({ kind: 'edit', label: '编辑' })
+  if (input.canArrange) {
+    primary.push({ kind: 'arrange', label: input.arrangeLabel })
+  }
+
+  more.push({ kind: 'copy', label: '复制' })
+  if (input.canWait) more.push({ kind: 'wait', label: '等客户通知' })
+  if (input.canCancelWait) more.push({ kind: 'cancel-wait', label: '取消等通知' })
+  more.push({ kind: 'print', label: '打印单据' })
+  if (input.canVoid) more.push({ kind: 'void', label: '作废', danger: true })
+
+  while (primary.length > 2) more.unshift(primary.pop())
+  while (primary.length < 2 && more.length) {
+    primary.push(more.shift())
+  }
+  return { primary, more }
+}
+
+function assert(cond, msg) {
+  if (!cond) {
+    console.error('FAIL:', msg)
+    process.exit(1)
+  }
+}
+
+const both = splitMpPlanDetailActions({
+  canEdit: true,
+  canArrange: true,
+  arrangeLabel: '安排运输',
+  canWait: true,
+  canCancelWait: false,
+  canVoid: true
+})
+assert(
+  both.primary.map((a) => a.kind).join(',') === 'edit,arrange',
+  'primary should be edit,arrange'
+)
+assert(
+  both.more.map((a) => a.kind).join(',') === 'copy,wait,print,void',
+  'more should be copy,wait,print,void'
+)
+
+const onlyVoid = splitMpPlanDetailActions({
+  canEdit: false,
+  canArrange: false,
+  arrangeLabel: '安排运输',
+  canWait: false,
+  canCancelWait: false,
+  canVoid: true
+})
+assert(onlyVoid.primary.length === 2, 'promote more into primary until 2')
+assert(onlyVoid.primary[0].kind === 'copy', 'first promoted is copy')
+assert(onlyVoid.primary[1].kind === 'print', 'second promoted is print')
+assert(onlyVoid.more.map((a) => a.kind).join(',') === 'void', 'void remains in more')
+
+console.log('check-mp-pl-plan-detail-actions: ok')

+ 44 - 0
web-admin/src/utils/mp-pl-plan-detail-actions.ts

@@ -0,0 +1,44 @@
+export type MpDetailActionKind =
+  | 'edit'
+  | 'arrange'
+  | 'copy'
+  | 'wait'
+  | 'cancel-wait'
+  | 'print'
+  | 'void'
+
+export type MpDetailAction = {
+  kind: MpDetailActionKind
+  label: string
+  danger?: boolean
+}
+
+/** 主栏最多 2 个:优先 edit、arrange;其余进 more */
+export function splitMpPlanDetailActions(input: {
+  canEdit: boolean
+  canArrange: boolean
+  arrangeLabel: string
+  canWait: boolean
+  canCancelWait: boolean
+  canVoid: boolean
+}): { primary: MpDetailAction[]; more: MpDetailAction[] } {
+  const primary: MpDetailAction[] = []
+  const more: MpDetailAction[] = []
+
+  if (input.canEdit) primary.push({ kind: 'edit', label: '编辑' })
+  if (input.canArrange) {
+    primary.push({ kind: 'arrange', label: input.arrangeLabel })
+  }
+
+  more.push({ kind: 'copy', label: '复制' })
+  if (input.canWait) more.push({ kind: 'wait', label: '等客户通知' })
+  if (input.canCancelWait) more.push({ kind: 'cancel-wait', label: '取消等通知' })
+  more.push({ kind: 'print', label: '打印单据' })
+  if (input.canVoid) more.push({ kind: 'void', label: '作废', danger: true })
+
+  while (primary.length > 2) more.unshift(primary.pop()!)
+  while (primary.length < 2 && more.length) {
+    primary.push(more.shift()!)
+  }
+  return { primary, more }
+}