Commit 9d72f98e authored by Joel Rennich's avatar Joel Rennich

docs

parent 98b12a59
......@@ -188,6 +188,7 @@
846DDD3B20191CD800D94821 /* NoMADActionMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoMADActionMenu.swift; sourceTree = "<group>"; };
846DDD3D2019422D00D94821 /* menu.nomad.actions.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = menu.nomad.actions.plist; sourceTree = "<group>"; };
846DDD3F201942C400D94821 /* NoMADActionCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoMADActionCommands.swift; sourceTree = "<group>"; };
846DDD41201A8A6700D94821 /* ACTIONS README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "ACTIONS README.md"; sourceTree = "<group>"; };
84847A661D3DDF5600FAE468 /* KlistUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KlistUtil.swift; sourceTree = "<group>"; };
84996CA71D503F8400793747 /* LDAPUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = LDAPUtil.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
84996CA91D503F9100793747 /* KerbUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KerbUtil.h; sourceTree = "<group>"; };
......@@ -384,6 +385,7 @@
846DDD39201919F800D94821 /* NoMADAction.swift */,
846DDD3B20191CD800D94821 /* NoMADActionMenu.swift */,
846DDD3F201942C400D94821 /* NoMADActionCommands.swift */,
846DDD41201A8A6700D94821 /* ACTIONS README.md */,
);
name = "Action Menu";
sourceTree = "<group>";
......
# NoMAD Actions Readme
This file lays out the design goals of the Actions Menu that you can add into NoMAD and how to use it.
## Philosophy
The Actions Menu is composed of "actions" which are defined by a prefrence file in the "menu.nomad.actions" domain. In this file Actions are listed as an array of dictionaries with each dictionary comprising one action. NoMAD Actions are simultaneously attempting to be highly configurable without being overly complicated.
## Anatomy of an action
An action is comprised of some meta data and then four phases. Each phase has a collection of Commands in them. These commands have the Command itself and then a CommandOptions that can modify the command. Commands can execute external scripts or use the built in functions included with Actions. The only required part of the Action is the name of the action, all the other parts are optional. To break out a sample Action
| Attribute |Definition |Type | Required
|---|---|---|---|---|
|Name| Plaintext name of the Action. Will be used for the menu name if a Title isn't given | String | yes
|Title| Command Set that determines the name of the menu item | Dictionary | no
| Show | Command Set that determine if the item should be shown in the menu | Array | no
| Action | Command Set that make up the actual Action itself | Array | no
| Post | Command Set that will happen after the Action commands are run | Array | no
| GUID | Unique ID for the Action | String | no
* Note that the Title command set can only have one command
* An Action with the Name of "Separtor" will become a separator bar in the menu.
## Commands
NoMAD has a number of built-in commands to make things easy, however, since one command is to execute a script, you'll quickly be able to make any unique commands that you want.
Each command has a CommandOptions value that determines what the command does. All options are strings. All commands can return results. A result of "false" is used by the Show action to prevent the menu item from being shown.
| Command | Function | Options
|---|---|---|
| path | Excute a binary at a specific file path | The path to execute
| app | Launch an app at a specific file path | The path to the application
| url | Launch a URL in the user's default browser | The URL to launch
| ping | Ping a host, will return false if the host is unpingable | The host to ping
| srv | Lookup up SRV records, returning false if they can't be found | The SRV records to lookup
| adgroup | Determine if the current user is a member of an AD group | The group to test with
| alert | Display a modal dialog to the user | Text of the dialog
* Note that Post action sets with an alert will automatically show the results of the Action set.
## Workflow
* On launch NoMAD looks at the `menu.nomad.actions` preference domain and reads in any Actions.
* For each Action, NoMAD will run the Show command set to determine if the menu item should be shown. Note that all commands in the Show command set have to return positive for the menu item to be shown.
* For items that pass the Show test, NoMAD will then run the Title command set to get the text of the menu item. If no command set has been configured, the Action name will be used instead.
* An item that is clicked on will cause the item's Action command set to be run.
* Following the Action set running, the Post set will then be run acting on the result of the Action set.
* Every time NoMAD updates (every 15 minutes, network change or NoMAD menu interaction) the Actions items will be updated with the same process.
## Still to come
There's a few more features that we'd like to get down before release. Currently all of these are achievable.
* Timers - Schedule the execution of an Action based upon a repeating time. Note that you can have "silent" Actions that do not show up in the Actions Menu, but do execute on a repeated schedule.
* Triggers - Trigger actions based upon system events such as:
* Network change
* Status images - Red/yellow/green dots next to menu items based upon the Show command set of the item. Currently you can "cheat" and use emoji in your menu titles.
\ No newline at end of file
......@@ -24,6 +24,7 @@ class NoMADAction : NSObject {
var showTest: [Dictionary<String, String?>]? = nil
var title: Dictionary<String, String?>? = nil
var action : [Dictionary<String, String?>]? = nil
var post : [Dictionary<String, String?>]? = nil
var preType: String? = nil
var preTypeOptions: [String]? = nil
......@@ -89,7 +90,6 @@ class NoMADAction : NSObject {
}
func displayItem() -> String {
return text
}
......@@ -101,15 +101,16 @@ class NoMADAction : NSObject {
} else {
myLogger.logit(.base, message: "Action failed: \(actionName)")
}
if post != nil {
// run any post commands
}
}
override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
print("********")
return true
}
func post() {
}
}
......@@ -47,13 +47,12 @@ public func runActionCommand( action: String, options: String) -> String {
}
}
}
return "false"
case "SRV" :
// TODO: use SRV lookup class here
break
case "groups" :
case "adgroup" :
if (defaults.array(forKey: Preferences.groups) as! [String]).contains(options) {
result = "true"
} else {
......
......@@ -78,6 +78,10 @@ let nActionMenu = NoMADActionMenu()
continue
}
if action.actionName.lowercased() == "separator" {
let separator = NSMenuItem.separator()
actionMenu.addItem(separator)
} else {
let menuItem = NSMenuItem.init()
menuItem.title = action.getTitle()
menuItem.target = action
......@@ -87,6 +91,7 @@ let nActionMenu = NoMADActionMenu()
menuItem.toolTip = "A NoMAD custom action"
menuItem.state = NSControl.StateValue(rawValue: 0)
actionMenu.addItem(menuItem)
}
}
//print(actionMenu)
//actionMenu.autoenablesItems = false
......
......@@ -1412,7 +1412,7 @@ class NoMADMenuController: NSObject, LoginWindowDelegate, PasswordChangeDelegate
if !self.NoMADMenu.items.contains(self.myActionsMenu) {
self.myActionsMenu.title = "Actions"
self.myActionsMenu.title = defaults.string(forKey: Preferences.menuActions)
nActionMenu.createMenu()
self.myActionsMenu.submenu = nActionMenu.actionMenu
self.NoMADMenu.addItem(self.myActionsMenu)
......@@ -1421,8 +1421,6 @@ class NoMADMenuController: NSObject, LoginWindowDelegate, PasswordChangeDelegate
nActionMenu.createMenu()
}
if self.userInformation.status == "Logged In" {
self.myShareMenuItem.title = defaults.string(forKey: Preferences.menuFileServers) ?? "FileServers".translate
......
......@@ -248,6 +248,7 @@ enum Preferences {
static let lastUser = "LastUser"
static let lastPasswordWarning = "LastPasswordWarning"
static let lastPasswordExpireDate = "LastPasswordExpireDate"
static let menuActions = "MenuActions"
static let menuChangePassword = "MenuChangePassword"
static let menuHomeDirectory = "MenuHomeDirectory"
static let menuGetCertificate = "MenuGetCertificate"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment