{"id":28478318,"url":"https://github.com/sangnandar/lookup-table-pattern","last_synced_at":"2025-07-03T07:32:31.089Z","repository":{"id":295882704,"uuid":"991574852","full_name":"sangnandar/Lookup-Table-Pattern","owner":"sangnandar","description":"This project shows how to handle dropdown changes in Google Sheets using a lookup table pattern in Apps Script for clean, scalable, and easy-to-maintain status transitions.","archived":false,"fork":false,"pushed_at":"2025-05-28T02:18:02.000Z","size":10,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-07T17:45:13.704Z","etag":null,"topics":["google-apps-script"],"latest_commit_sha":null,"homepage":"https://script.google.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sangnandar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-27T20:46:11.000Z","updated_at":"2025-05-28T02:18:06.000Z","dependencies_parsed_at":"2025-05-27T21:42:37.383Z","dependency_job_id":"655bc02f-6b96-4e16-b82c-c25b71e1f274","html_url":"https://github.com/sangnandar/Lookup-Table-Pattern","commit_stats":null,"previous_names":["sangnandar/lookup-table-pattern"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sangnandar/Lookup-Table-Pattern","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sangnandar%2FLookup-Table-Pattern","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sangnandar%2FLookup-Table-Pattern/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sangnandar%2FLookup-Table-Pattern/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sangnandar%2FLookup-Table-Pattern/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sangnandar","download_url":"https://codeload.github.com/sangnandar/Lookup-Table-Pattern/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sangnandar%2FLookup-Table-Pattern/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263282789,"owners_count":23442249,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["google-apps-script"],"created_at":"2025-06-07T17:34:56.119Z","updated_at":"2025-07-03T07:32:31.080Z","avatar_url":"https://github.com/sangnandar.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 📋 Lookup Table Pattern in Apps Script\n\nThis project demonstrates an efficient and maintainable way to handle dropdown value changes in Google Sheets using Google Apps Script. By leveraging a **lookup table pattern (dispatch table)**, it enables scalable, readable, and flexible management of status transitions—ideal for workflows like order processing, task tracking, or any state-based automation.\n\nIt promotes clean separation of business logic, reduces complex conditional code, and simplifies adding or updating workflow steps.\n\n## ❓ Why This Pattern?\n\nTraditional `if/else` or `switch` statements can quickly become hard to read and maintain—especially when handling many status transitions with complex branching.\n\nThe **lookup table pattern** solves this by using a **dispatch table**: a plain object that maps values to functions. This keeps logic **declarative**, **modular**, and **scalable**:\n\n* ✅ **Easier to maintain** – Add or change transitions in a single config file\n* ✅ **No duplicate logic** – Avoids repeating code for similar transitions\n* ✅ **Improves readability** – The structure clearly shows what transitions are allowed\n* ✅ **Reduces bugs** – Each handler is isolated and easy to test\n\nThis pattern is ideal when you want to enforce specific business rules tied to dropdown selections, without bloating your main logic.\n\n\n## 💡 What It Does\n\n### Business process\n\n```mermaid\ngraph LR;\n  a[Waitlist] --\u003e b[Booking] --\u003e c[Confirmation] --\u003e d[Send Invoice] --\u003e e[Paid] --\u003e f[Delivery];\n  a --\u003e c;\n  c --\u003e e;\n```\n\n### Workflow\n\n* Detects **dropdown changes** in a target column of a specific sheet (**column A** in sheet **\"Orders\"**)\n* Validates transitions against a predefined map `ORDERSTATUS_CONFIG`\n* Calls the corresponding **handler function** for valid transition\n* Ignores invalid or unsupported transitions silently or with optional alerts\n\n\n## 🧠 Pattern Overview\n\nThis project uses a **dispatch table** (lookup object) to determine which function to call when a dropdown value changes:\n\n```javascript\nconst ORDERSTATUS_CONFIG = readOnlyObject({\n  'Waitlist': {\n    bgColor: '#ffcfc9',\n    transitions: {\n      'Booking': handleBooking,\n      'Confirmation': handleBooking\n    }\n  },\n  'Booking': {\n    bgColor: '#d4edbc',\n    transitions: {\n      'Confirmation': handleBooking\n    }\n  },\n  'Delivery': {\n    bgColor: '#15dae7',\n    transitions: {}\n  }\n});\n```\n\nTransitions not listed in `ORDERSTATUS_CONFIG` are safely ignored.\n\n\n## 🗂 File Structure\n\n| File                  | Purpose                                                                 |\n| --------------------- | ------------------------------------------------------------------------|\n| `action-handlers.gs`  | Handler functions for specific dropdown transitions                     |\n| `config.gs`           | Centralized config for sheet name, editable column, and transition map  |\n| `triggers.gs`         | Sets up simple and installable triggers                                 |\n| `trigger-handlers.gs` | Handler functions for triggers                                          |\n| `utils.gs`            | Utility and helper classes/functions                                    |\n\n\n## 🔍 How It Works\n\nWhen a user **changes a dropdown** the `edit(e)` function does the following:\n\n```mermaid\ngraph TD;\n  a0[Edit event] --\u003e a{Is it column 'orderStatus'\u003cbr\u003ein sheet 'Orders'?}\n  a --\u003e |No| return1[Exit]:::return\n  a --\u003e |Yes| b[Dispatch to\u003cbr\u003etrigger-handler] --\u003e c{Does the sheet\u003cbr\u003econtains data?}\n  c --\u003e |No| return2[Exit]:::return\n  c --\u003e |Yes| d{Is the transition\u003cbr\u003eallowed?}\n  d --\u003e |No| return3[Exit with alert]:::return\n  d --\u003e |Yes| e[Read the row\u003cbr\u003eand call handler] --\u003e f[Execute action-handler];\n\n  classDef return fill:#f96;\n```\n\n\n## 🧪 Example Use Case\n\nSuppose you have a dropdown in column A of your \"Orders\" sheet:\n\n| Status (Col A)  | Order ID    | Client Name |\n| --------------- | ----------- | ----------- |\n| `Waitlist`      | V8K3J1T7PQ  | Alice       |\n| `Confirmation`  | XG5PLQ7YTZ  | Bob         |\n\nWhen a user changes:\n\n* `Waitlist → Booking`\n  → `handleBooking()` is executed\n\n* `Confirmation → Paid`\n  → `handleInvoice()` is executed\n\n\n## 🧩 Related Projects\n\nThis project builds on the **[Dynamic Google Sheets Layout](https://github.com/sangnandar/Dynamic-Google-Sheets-Layout)** pattern to keep sheet references clean, maintainable, and column-safe.\n\nIf you're managing Google Sheets by column **names** instead of hardcoded indexes, check it out!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsangnandar%2Flookup-table-pattern","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsangnandar%2Flookup-table-pattern","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsangnandar%2Flookup-table-pattern/lists"}