Actions

An action is something done to the rows of a view: a row added, copied, pasted or deleted, or whatever a view of your own says. This page is about where actions are offered, what each of the standard ones does to a record and to a list, and how a perspective gets actions of its own.

Where actions come from

Every view is a perspective, and a perspective is built from lists. Each list says what may be done to its rows: whether Add / Insert, Copy & Paste, Delete and, in a list that keeps an order of its own, Move up / down are offered at all, whether each stands in the action bar or waits on the menu, in what order, and wearing what face. Those settings are the Actions fold of each list in the perspective editor. What an action does is not the perspective’s to say: adding, copying and deleting work the same way in every view, so that a view you have never seen before holds no surprises. A perspective may also add actions of its own, built from steps, and those stand beside the three wherever the three are offered.

Actions are offered in three places, and all three act on the same thing: the record or the list the cursor is on. The cursor is the row or the list with the frame round it; while nothing is selected it rests on the view’s top-level list. The three places are the context menu, the action bar at the foot of the view, and the keys.

Right-click anything in a view, or hold it on a phone or tablet, and a menu opens with what can be done to what you pressed. It acts on what you pressed, whether or not that was selected: the cursor stays where it was. What the menu holds depends on where you pressed.

Each item shows the key that does the same. An action the perspective does not offer is simply not there; one that cannot be done at this moment is greyed: the file is read-only, the list already has as many rows as it allows, there is nothing to copy, or the clipboard holds nothing that belongs in this list. A press that has nothing to offer opens no menu at all.

The menu from a right-click on a term: Edit term, Open term with, Copy text, Expand in place, Open expanded, Insert, Copy record, Paste rows and Delete record, with their keys.
The menu on a term: what can be done with the term first, then what its record offers.
The menu from a right-click on the view's empty space: Add to list, Copy all rows, Paste rows greyed, two actions of the view's own called New engineer and Make lead, and Delete all rows (6 triples).
The menu on the view’s own space is the top-level list’s. This view has two actions of its own.

The action bar

The same actions stand as buttons in the bar floating at the foot of the view, for whatever is selected: the record, the list, or the top-level list while nothing is. A perspective says which of its actions are in the bar and in what order; every action of a new list starts there, and a quieter tick on its card takes it out again, leaving it to the menu and its key. The bar stays at the foot however far the view is scrolled, and a view whose perspective shows nothing there has no bar.

Hover a button for its name and its keys. The buttons answer the digits by their place: 1 presses the first button from the left, 2 the second, up to 0 for the tenth, on the number row or the numeric keypad. A key per place rather than per action, so that the first button is always 1 whatever the perspective has put there; a bar with more than ten buttons has the rest pressed by hand. The one button no key presses is Delete all rows: the cursor rests on the top-level list whenever nothing else is selected, and a digit pressed by mistake must not empty the file. A greyed button is greyed for the same reasons as a greyed menu item, and shows none of its colours while it is.

The record for ada selected, and the action bar at the foot with six buttons: insert, copy, paste greyed, delete, a person icon with the tooltip New engineer (5), and a button lettered Ld.
The bar for a selected record. The last two buttons are the view’s own actions; the tooltip names one and the key that presses it.

The standard actions

Three actions come with every list, and a fourth with every list that keeps an order of its own; the app decides what they do. Each is one step to undo, however many statements it touched: Ctrl+Z, or the arrow in the app bar. The keys named here are the defaults on Windows and Linux; a Mac has ⌘ where they have Ctrl, and all of them can be changed.

Add / Insert

Makes a row the list’s own conditions accept, so that adding to a list of people makes a person. A condition that pins a part, such as relation is rdfs:label or subject is the subject above, decides that part of the new row; a part the conditions leave open starts as the list’s Defaults say, or, left on auto, as the app answers: a fresh name in the file’s namespace for a subject, rdf:type for a relation, and an empty value of the kind the field holds. A row is seldom one statement, so an Add may make a whole tree of statements under the row’s own, and may make the rows the lists nested under it ask for; the perspectives page says how that is set up. The new row is brought into view.

On a record it is called Insert: in a list that keeps an order of its own the row goes in above the record, and in a list the file orders it joins the list. On a list it is called Add to list, and the row goes at the end. Insert or + does either, for whatever is selected. It is greyed when the file cannot be written or the list already has the most rows it allows.

Copy & Paste

Copy record takes the selected record with everything nested under it: the rows of its nested lists whose own Copy is on, and theirs in turn, and what an invoked view shows under the row, as far down as that goes. Copy all rows takes every row of the list the same way. Either goes to the system clipboard as text, so it can travel between windows and between files. Ctrl+C copies; Ctrl+Insert does the same.

Paste rows puts copied rows into a list of the same kind: the same list of the same view, under another record, or in another file opened with the same view. It is greyed until the clipboard holds rows that belong in the list under the cursor. On a record in a list that keeps an order of its own the rows go in above it; otherwise they join the list, or go at its end. Each pasted row is made the way an Add would make it, so the parts the list’s conditions pin come from where it lands: the same attributes, said about another subject. Named terms keep their names; anonymous nodes come along as new anonymous nodes with everything said about them. A row the list already has is not added again, with one exception: in a list of distinct items, pasting an item the list already has makes a copy of it under a new name, alice becoming alice2. Ctrl+V pastes; Shift+Insert does the same.

Delete

Delete record takes the selected row with everything under it: the rows its nested lists show, where those lists’ own Delete is on, and theirs in turn; and the anonymous nodes the deletion leaves nothing pointing at, whole, down to the last. A row that comes from an imported file is not this file’s to delete and stays where it is. The menu says how many statements that comes to. Delete all rows does the same for every row of the list. Delete or Backspace deletes the selected record; a whole list is deleted from its menu or its button only. Deleting is greyed when the file cannot be written, and a list that must keep some rows (its Min) cannot be emptied.

Two ticks on the list’s Delete card say how far “everything under it” reaches: Delete the subordinates’ rows too and Delete blank nodes left orphaned. Unticked, the row goes alone, or the orphaned nodes are left standing. What a view does not show, it never deletes: a subject named by an IRI may well be described elsewhere, and only what the view spoke for goes.

Move up / down

In a list that keeps an order of its own, a row’s place is a number in the file, and Move up and Move down change it: the two neighbours swap numbers. The record’s menu offers the pair, the bar draws it as two buttons, and Alt+↑ and Alt+↓ do the same. Each is greyed at the end of the list in its direction, and both when the file cannot be written. It is a card like the others in the list’s Actions fold, and appears once the list is sorted in numeric order (Sort, under Configuration). In a list the file orders there is nothing to move a row to, and the action is not there, whatever the card says. A list has no place of its own: the pair is a record’s alone.

A record, or a list

The same action means something different on a record and on a list, and the menu names it accordingly. The bar and the keys do what the menu would, for whatever is selected.

ActionOn a recordOn a list
Add / InsertInsert: a row above the record where the list keeps an order of its own, into the list otherwise.Add to list: a row at the end.
CopyCopy record: the record with everything under it.Copy all rows: every row, each with everything under it.
PastePaste rows: above the record where the list keeps an order, into its list otherwise.Paste rows: at the end.
DeleteDelete record: the record with everything under it. Delete does it.Delete all rows: every row with everything under it. No key does it.
Move up / downThe record one place up or down, in a list that keeps an order of its own.Not offered: a list has no place of its own.
An action of the view’s ownIts steps run under the record’s row.Its steps run under the row the list hangs off; on the top-level list, under nothing at all.

Which list is selected matters too. Click a nested list’s heading and the cursor is on that list: Add to list then adds under the record that holds it, and Delete all rows empties that one list. Click the view’s title or its empty space and the cursor is on the top-level list, which is also where it rests while nothing else is selected. So with nothing selected the bar is the top-level list’s, and Insert adds a record at the end of the view.

Actions of your own

A perspective can carry actions beside the three. Add action, at the foot of a list’s Actions fold in the editor, makes one: a card like the others, with a name of your choosing in place of the app’s, the same two ticks and arrows, a face to pick, a cross to take it away, and under them Steps: what the action does, in order, to the row it is pressed on. It is then offered wherever the three are, on the record’s menu and the list’s and in the bar, and the bar’s place keys press it. It has no key of its own. It is greyed whenever the file cannot be written, since what its steps come to is theirs to say.

The editor's Actions fold: cards for Add / Insert with its Defaults and After insert, Copy & Paste, Delete with its two reach ticks, and an action named New engineer whose steps are a Call of Add / Insert with an Insert under it making the predicate role and the value Engineer.
The Actions fold of the People list: the three cards, and under them New engineer, an action of the view’s own.

Every step runs under a statement: the action’s own steps under the row the action was pressed on, which is the record’s own statement, or, pressed on a list, the row that list hangs off. In a step’s cells, ↑subj, ↑pred and ↑obj are the parts of that statement, and a second ancestor counts on up from it, the way a nested list’s conditions count up the rows above it. Steps are written in the same words as the rest of the editor: a condition is a condition, a value is a value, and nothing is typed as text.

The six kinds of step

Four are SQL’s words, said of a graph; the fifth hands the work to another action; the sixth puts the steps under it within a graph of the file.

The whole action is one step to undo, and where a Call made a row, that row is brought into view as an added row would be. A step that changes or deletes a row from an imported file does nothing: that row is not this file’s.

Steps under steps

Select, Call and Within graph are the kinds that have steps of their own, and most of what an action can do is said with them. The view in the pictures has two actions. New engineer is a Call of the list’s Add / Insert with an Insert under it: the Add makes a new person the usual way, numbered where the list keeps an order and with whatever its nested lists ask for, and then the Insert says what is particular to this action, :role "Engineer" about the person just made. Make lead is a Select for the one statement whose subject is ↑subj, the person the action was pressed on, and whose relation is :role, with a Max of 1, and an Update under it setting the value to "Lead". Give that Select a Min of 1 as well and it makes the role where the person has none before the Update sets it: a Select for one statement with a Min of 1 and an Update under it is an upsert, said without a word for it. A Select under a Select is a join, and an Insert under a Select reads what the Select found.

The card for the action Make lead: its Steps hold a Select whose When reads subject equals the subject above and predicate equals role, with Max 1, and under it an Update whose Object is the text Lead. Under the card, a line says that Move up / down joins the actions once the list is sorted in numeric order.
Make lead: a Select with its conditions and its Max, and the Update that runs under what it finds. The line under the card says where Move is switched on: this list is not sorted in numeric order.

Within graph is how an action computes a graph: a Select over the file, and under it Within graph with an Insert, says for each statement found, say this in that graph. Ticked temporary, the graph is a view of the file that lives for the session — derived statements, scratch notes, a report — and is gone with it; untick it and the same action builds a graph the file keeps. The steps under Within graph still read ↑subj and the other parts of the statements above them, wherever those statements are; a term from another graph is carried into the named graph by its name, and an anonymous node by its label, which within one file is the same node.

Pressed on a list rather than a record, an action’s steps run under the row the list hangs off, and on the top-level list under nothing at all. New engineer works there too, since its Call adds to the list as Add to list would; Make lead finds nothing, since there is no ↑subj to read. An action meant for records is best left to records.

Faces

Any action, the standard ones included, may wear a face of the perspective’s choosing: press the square on its card. The dialog offers fifty built-in icons, or one or two characters of your own in an icon’s place, and a colour for either and for the square behind it: a theme colour, which keeps its meaning in light and dark alike, or one of your own. The icon is drawn wherever the action is, on the menu as in the bar; the characters and the colours wherever it is drawn as a button. An action of your own with no face wears a bolt on the menu. In the pictures, New engineer wears the person icon, and Make lead the letters Ld in the bar and the bolt on the menu.

How an action is stored

This section is for the curious and for those who write views by hand or have an AI draft them. You can skip it.

Actions are part of the list they belong to, in the same RDF document as the rest of the perspective. The standard ones are written only where they depart from their resting state: ars:adding, ars:copying, ars:deletion and ars:moving nodes with ars:offered false for never, ars:inActionBar false for the menu and the key alone, and ars:order for a place in the bar other than their own, Move’s own being after the other three. The ars:adding node also carries what a new row starts as, ars:subjectDefaultValue and kin, the further statements the press makes as ars:alsoMakes nodes, and ars:addsSubordinates false where the nested lists’ rows are not made along with it; the ars:deletion node carries ars:deletesSubordinates false and ars:deletesOrphans false where a deletion is to reach less far. A face is ars:icon "delete_forever" or ars:glyph "☠", with ars:color and ars:background: a theme colour as av:primary and kin, or a "#AARRGGBB" string.

An action of the view’s own is an ars:action of the list: an ars:CustomAction node with its ars:label, its ars:order among the actions, the same standing and face, and its ars:steps in order. Here are the two actions from the pictures as the app saves them, on the People list from the perspectives page:

p:people a ars:DataSource ;
    ars:subjectVisible true ;
    ars:distinctBy rdf:subject ;
    ars:filter [ … subject has type :Person … ] ;
    ars:action [
        a ars:CustomAction ;
        ars:label "New engineer" ;
        ars:icon "person" ;
        ars:order 3 ;
        ars:step [
            a ars:CallStep ;
            ars:calls ars:adding ;
            ars:order 0 ;
            ars:step [
                a ars:InsertStep ;
                ars:order 0 ;
                ars:predicateDefaultValue [ a ars:IriValue ;
                    ars:nsUri "http://ex/team#" ;
                    ars:localName "role" ] ;
                ars:objectDefaultValue [ a ars:LiteralValue ;
                    ars:literal "Engineer" ] ] ] ], [
        a ars:CustomAction ;
        ars:label "Make lead" ;
        ars:glyph "Ld" ;
        ars:order 4 ;
        ars:step [
            a ars:SelectStep ;
            ars:order 0 ;
            ars:maxCount 1 ;
            ars:filter [
                a ars:FilterAnd ;
                ars:operand [
                    a ars:FilterCompare ;
                    ars:order 0 ;
                    ars:left [ a ars:TermValue ; ars:role rdf:subject ] ;
                    ars:op ars:eq ;
                    ars:value [ a ars:TermValue ;
                        ars:role rdf:subject ;
                        ars:bindingDistance 1 ] ], [
                    a ars:FilterCompare ;
                    ars:order 1 ;
                    ars:left [ a ars:TermValue ; ars:role rdf:predicate ] ;
                    ars:op ars:eq ;
                    ars:value [ a ars:IriValue ;
                        ars:nsUri "http://ex/team#" ;
                        ars:localName "role" ] ] ] ;
            ars:step [
                a ars:UpdateStep ;
                ars:order 0 ;
                ars:objectNewValue [ a ars:LiteralValue ;
                    ars:literal "Lead" ] ] ] ] ;
    ars:child p:props .

A few things to know when reading or writing one:

Try one: open the demo, pick a tab, press Configure, open the Actions fold of the top list and press Add action. The view under the form follows each change.