Skip to main content

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 🙏

 

 

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. 
 

  1. Create a new table for the project/initiative status like suggested by Felipe
  2. 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.
  3. 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 recordIdRecord (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. 
 

 


Hey ​@Jakub_Szerszen,

You might want to fill out this feature request form!

Mike, Consultant @ Automatic Nation 


Reply