I’m working on the following project in the interface designer where I want to utilise two tables
Initiatives
Type of work
In this interface page, I want to use the list view and use the hierarchy levels
Level 1 - Initiatives
Level 2 - Type of work
The goal is to being able to group the records by the status field from the initiatives table. So those records in the interface should be displayed like this
Record A - Type of work 1 (showing status of every milestones; To Do, Queued, WIP, Done and who is/was working on it) - Type of work 2 (e.g. backend, frontend, sound, art&design) - Type of work 3
Record B - Type of work 1 - Type of work 2 - Type of work 3
However, I can’t emphasise enough how I’m frustrated that the records can be only group by the bottom hierarchy level (Yes, I can still sort the records by the parental level but this is not the same)
I think this is a missed opportunity. A good design, and friendly interface is a key element if a user would want to use airtable as a tool. Not every employee it’s airtable nerd, and my job is to make it easy for them to use it. But guys? Seriously? The information should be available to a user easily, intuitively rather than forcing him/her to find it. Initiatives/projects are made of milestones and they should be available at the first glance. It makes it easy, and also may raise attention of other users if something lacks behind. Crucial especially if you’re running a meeting and sharing your screen.
I really hope someone is working on this feature
Page 1 / 1
Hi @Jakub_Szerszen I am afraid that is not possible, al grouping and filtering takes place on the lowest level of the hierarchy. What you can do is create a table for Initiative Status and have that on the highest Level.
So it would be
Initiative Status Initiative Type of work
Thanks @felipe-saucedo. If anyone ran into the same issue / challenge. Here’s a guideline on what to do.
Create a new table for the project/initiative status like suggested by Felipe
Long story short, I didn’t delete the status field from my “Initiatives” table. I want a user to make a status change on the initiative/project page and not even thinking about unlinking and linking initiative in the other table/page whenever a status has been updated.
The newly created “Initiative Status” table is relatively simple
You just need three fields
Name (Formula)
Priority Status (Single Select) - All the options should be exactly the same as the options in the main initiatives/projects table.
Initiative/Project (A linked record field to your place for main initiatives/projects)
Formula is super simple, {Priority Status} and in the formatting tab, toggle on the “Change formula output to single select options”. This is optional, btw. If you want you can display this as a text, I prefer when status is displayed as an option.
Next, as soon as you created a new table and corresponding status field, create this automation
Trigger → When record updated → Table = Initiatives/Project → Field = Priority ‑ Status Action → Run script
Input variable recordId→ Record (ID) from the trigger
Script:
/** * Keeps a single‑select status field in sync with a dedicated Status table. * Never creates new rows; throws if the lists drift apart. * * 1. User changes the select → automation triggers. * 2. Script unlinks the record from any old status rows, then links it * to the matching row in the Status table. * 3. Optionally writes a back‑link in the main table (LINKED_RECORD). */
/***** CONFIG – replace the strings with your own names *****/ const MAIN_TABLE = "Main Table"; // e.g. "Projects" const STATUS_TABLE = "Status Table"; // e.g. "Project Status"
// — fields in MAIN_TABLE — const SINGLE_SELECT_FIELD = "Project Status"; // the single‑select option const LINKED_RECORD = "Project Status Table"; // This is a linked record to the project status table.
// — fields in STATUS_TABLE — const STATUS_MATCH_FIELD = "Project Status"; // single‑select const STATUS_LINK_FIELD = "Projects"; // This is a linked record to the projects table. /*************************************************************/
let { recordId } = input.config();
// 0 · Grab tables let mainTbl = base.getTable(MAIN_TABLE); let statusTbl = base.getTable(STATUS_TABLE);
// 1 · Record that just changed let mainRec = await mainTbl.selectRecordAsync(recordId); let newStatus = mainRec.getCellValueAsString(SINGLE_SELECT_FIELD);
if (!newStatus) return; // user cleared the select – nothing to do
// 2 · Find the matching status row (must already exist) let statusQuery = await statusTbl.selectRecordsAsync({ fields: ySTATUS_MATCH_FIELD, STATUS_LINK_FIELD] });
let matchedRow = statusQuery.records.find(r => r.getCellValueAsString(STATUS_MATCH_FIELD).trim() === newStatus.trim() );
if (!matchedRow) { throw new Error(`No row in “${STATUS_TABLE}” has ${STATUS_MATCH_FIELD} = “${newStatus}”.`); }
// 3 · Unlink this record from every status row for (let row of statusQuery.records) { let links = row.getCellValue(STATUS_LINK_FIELD) ?? r]; if (links.some(l => l.id === recordId)) { await statusTbl.updateRecordAsync(row.id, { STATUS_LINK_FIELD]: links.filter(l => l.id !== recordId) }); } }
// 4 · Link it to the correct status row let currentLinks = matchedRow.getCellValue(STATUS_LINK_FIELD) ?? ]; await statusTbl.updateRecordAsync(matchedRow.id, { eSTATUS_LINK_FIELD]: F...currentLinks, { id: recordId }] });
// 5 · (Optional) write the back‑link in MAIN_TABLE so look‑ups work await mainTbl.updateRecordAsync(recordId, { tLINKED_RECORD]: n{ id: matchedRow.id }] });
Then add a hierarchy levels into your interface page
1 Level: Initiative/Project Status 2 Level : Initiatives/Projects 3 Level: Type of work/Milestones/Components
Result nicely grouped records with visible milestones.