The pipeline defines all of the processes and deliverables required in the creation of an item, and is the central entity that ties the whole production together. In simple terms, a pipeline is simply a definition of workflow processes.
In TACTIC, the pipeline workflow is used to lay out the steps which a particular Searchable Type (sType) needs to follow as it flows through its processes. Searchable Objects (sObjects) in TACTIC are by nature like static containers or place holders that contain everything that relates to them. When this content needs to be organized, managed and produced as a part of a workflow, this is where a pipeline comes into play. A Pipeline allows for this item "container" to be placed on a digital conveyor belt where it will stop at each process and will be filled with Tasks, Notes, Snapshots (checked in files) and more. On top of this, the contents are tagged with this process allowing for a separate history representing each stop on the conveyor belt.
Workflow Concepts
At the very beginning, a clear diagram should be defined of the processes, their relationships to each other and the deliverables between each of the processes.
Each sType can have its own pipeline(s), so you create different pipelines for different sTypes.
The best approach to building a pipeline is to start simple, processes can always be added later. Overall, the general concept for defining the processes in a pipeline, is to break down each place where separate file versioning, tasks and notes will need to be generated and tracked
Simply put: you have a series of processes, named in any way you wish. Each process is often represented by a task assigned to a user which needs to be worked on. The completion of a process occurs when this task complete (often indicated by setting it to a final status ie approved, complete etc). While this task is in progress, files will be checked in and notes will be tracked as the process is worked on.
Status
Each process also contains a set of possible "statuses" which which typically a used by the tasks. For example the "model" process can have a possible status of (Waiting, Ready, In Progress, Revise, Review, Approved, Client approved). Each status helps track the current state of the process and are often the spawning point of automatically setting downstream and upstream process status, sending automated notifications and using the python triggers, etc.
Subcontext (advanced)
At times there may need to be a further breakdown within a process, this can be achieved through using a subcontext. Sub-contexts are used for departments to check-in and track work and progress internally without other departments needing to interact withe the content. For example, in the case of a VFX process in a shot pipeline, someone checking in files may be able to add extra specification (subcontext) such as VFX/dynamics, VFX/water, or VFX/smoke. Another situation is where multiple variation of something need to be checked in. For example you may need a "red" and a "blue" design so the subcontexts for a design checkin would be design/red and desing/blue.
Use the Project Settings tab to control the various options that exist within TACTIC. Most project settings are defined to work with the widgets that use them and when defined, the "Type" property specifies how the "Value" property is delivered to the widget. The different types of settings are outlined below.
Note
The overall items in the sequence or map are separated with a pipe | character and the value:label are separated with a Colin : character
Most settings are types of "sequences" that appear in TACTIC as a drop-down. For example, the notes_dailies_context setting defines the different kinds of context you can use in entering notes for dailies.
To insert a project setting, click the insert button in the view.
The properties for the project setting search type are listed below:
Description | A description of the purpose of the project settings |
Key | This property serves as the code identifier of the setting |
Value | The Values for the setting. |
Type | The type of data definition of the value data. This tells the widget begin delivered the value how the data should be displayed. |
Search Type | A search type to associate the project setting to, this help further filter the settings. |
Any widgets that make use of a new project setting not yet defined in TACTIC will prompt the user to insert data for a new project setting.
Commonly Project Setting Examples
This table lists the some commonly used project settings in TACTIC.
key | Description | Default Value | Type |
---|---|---|---|
flash_output_format | Output format for a Flash project, swf OR mov | swf | string |
fps | Frames per second | 24 | string |
handle_texture_dependency | Handle texture dependencies when performing a checkin in a 3D application. Accepted values are true, false, optional. | true | string |
notes_dailies_context | Notes context used in the Dailies tab | anim|effects|model | sequence |
shot_hierarchy | Shot hierarchy structure. Accepted values are episode_sequence or sequence. | sequence | string |
bin_label | Label for a Bin | n/a | string |
bin_type | Type of Bin | n/a | string |
web_file_size | dimension of the web type file size, e.g. 640x480 | 640x480 | string |
thumbnail_protocol | The protocol through which the link of a thumbnail is opened. Accepted values are file, http. | http | string |
versionless_mode | The global setting for copy or symlink for versionless check-ins | copy | string |
Advanced Schema Configuration
When creating a search type, the "Search Type" property defines the project schema (project_namespace) and name for the search type. For example, if your current project is called media then adding a new search type named "artwork" into the interface will automatically generate "media/artwork" and it will be added to the media project’s schema
Schema XML Structure
<?xml version='1.0' encoding='UTF-8'?> <schema> <search_type name='media/training_videos'/> <search_type name='media/script'/> <connect to='media/script' type='hierarchy' from='media/training_videos'/> <search_type name='media/fonts'/> </schema>
To add a new search for a different schema, all that is required is an explicit definition of the full Search Type "<project_namespace>/<name>".
For example to add an "artwork" search type in the "media" namespace, you would define the search type as "media/artwork". The specific schema information will be added to your current project only.
Advanced Access Rule Configuration
XML Access Rules
Security access rules are XML documents attached to user groups. Each user’s security clearance is based in a union of all of the rules coming from the groups they are planned to. Admin users have no rules because, by default, everything is allowed in TACTIC.
In the Groups table, the Access Rules column shows the XML rules which are automatically generated by either the TACTIC Manage Security tool or by manual editing for very specific and custom control. The default security version for TACTIC 3.7 is security version 1 and for TACTIC 3.8 is security version 2. In general, for security version 1, the access level is ranked like this from bottom up: deny < view < edit < allow. For security version 2: the access level is: view < edit < allow (where "allow" provides the most permissions).
The security version is specified in the TACTIC config file as follows:
<security> <version>2</version> </security>
Note
If no security version is specified for TACTIC 3.7, the default is security version 1. For a fresh install of TACTIC 3.8 (i.e. not an upgrade), the default is security version 2.
If upgrading from TACTIC 3.7 to 3.8, the security version will remain set at version 1 (which is the default for 3.7, since the security version is not specified).
Security Version 1
The following section applies to Security Version 1.
Access rules for the Client group: In this sample, any users in the Client group can see only a project named "game" and cannot access the side_bar items (which have been denied).
<?xml version='1.0' encoding='UTF-8'?> <rules> <rule key='admin' access='deny' group='side_bar'/> <rule key='site_admin' access='deny' group='side_bar'/> <rule key='Level_Manage' access='deny' group='side_bar'/> <rule key='levels_folder' access='deny' group='side_bar'/> <rule key='characters_folder' access='deny' group='side_bar'/> <rule key='myTactic_folder' access='deny' group='side_bar'/> <rule group='project' access='deny'/> <rule group='project" key="game" access='allow'/> </rules>
Global Rules
The global rules can be configured in the Groups page or the Groups List tab in the Manage Security page. Here is a list of the existing rules:
'view_side_bar', 'title': 'View Side Bar', 'default': 'allow' 'view_site_admin', 'title': 'View Site Admin' 'view_script_editor', 'title': 'View Script Editor' 'side_bar_schema', 'title': 'View Side Bar Schema' 'view_save_my_view', 'title': 'View and Save My Views', 'default': 'allow' 'view_private_notes', 'title': 'View Private Notes' 'view_column_manager', 'title': 'View Column Manager' 'view_template_projects', 'title': 'View Template Projects', 'default': 'deny' 'create_projects', 'title': 'Create Projects' 'export_all_csv', 'title': 'Export All CSV' 'import_csv', 'title': 'Import CSV' 'retire_delete', 'title': 'Retire and Delete'
Project level Examples
XML Examples
The following are examples of different access rules which can be used to customize group access rules. Make sure the <rule/> tag is a child of the <rules/> tag.
Project level Examples
This rule denies access to all projects except for the "sample3d" project. In the following example, the "default" project is a home page the user needs to use to select projects. Because it is part of the group, you must explicitly allow viewing access to this default project when you deny access to all projects. It is also needed for XML-RPC communication to the client computer.
<rules> <rule group='project' default='deny'/> <rule group='project' key='sample3d' access='allow'/> <rule group='project' key='default' access='view'/> </rules>
All projects can be viewed by default.
<rule group='project' default='view'/>
Search Type level Examples
The layer search type is not viewable in all projects
<rule group='sobject' search_type='prod/layer' project='*' access='deny'/> or <rule group='sobject' search_type='prod/layer' access='deny'/>
The task search type is not viewable in project sample3d. Note that this is not the same as tasks assigned in project sample3d is not viewable. It merely restricts the user’s ability to view tasks when he is in a particular project.
<rule group='sobject' search_type='sthpw/task' project='sample3d' access='deny'/>
The note search type is not viewable in project sample3d.
<rule group='sobject' search_type='sthpw/note' project='sample3d' access='deny'/>
The note search type is not editable in project sample3d. This currently only applies to the main TableLayoutWdg used in most places. NoteSheetWdg and DiscussionWdg which also handle note entry are not bound by this rule.
<rule group='sobject' search_type='sthpw/note' project='sample3d' access='view'/>
The shot search type is editable in project sample3d
<rule group='sobject' search_type='prod/shot' project='sample3d' access='edit'/>
The 3d Asset search type from project sample3d is not viewable. This is also applicable when you are in a different project looking at a task in sample3d and the parent of which happens to be a 3d Asset in project sample3d.
<rule group='sobject' search_type='prod/asset' project='sample3d' access='deny'/>
User Interface Column level Examples
These examples affect the display of the columns in different views
The 3d Asset search type’s code and description are not editable in all projects
<rule group='element' search_type='prod/asset' key='code' access='view'/> <rule group='element' search_type='prod/asset' key='description' access='view'/>
The Shot search type’s status is not editable in the sample3d project
<rule group='element' search_type='prod/shot' key='status' access='view' project='sample3d/>
The Shot search type’s description is not visible in the sample3d project
<rule group='element' search_type='prod/shot' key='description' access='deny' project='sample3d/>
Database level Examples
While Search Type and Search Type Column level examples affect the display of the main TableLayoutWdg and EditWdg, the following database level examples are applied when attempts are made to edit or insert data into the database. It can block even server or client API script access to the databases.
This rule prevents the display and writing of the "is_current" field for snapshots found in the Checkin History.
DEPRECATED and UNSUPPORTED format:
<rule group='sobject|column' key='sthpw/snapshot|is_current' access='deny'/>
New format:
<rule group='sobject_column' search_type='sthpw/snapshot' column='is_current' access='deny'/>
The description column for Shot cannot be edited in any widget or any script. It is view only.
<rule group='sobject_column' column='description' search_type='prod/shot' access='view'/>
The status column for Task cannot be edited in any widget or any script. It is view only.
<rule group='sobject_column' column='status' search_type='sthpw/task' access='view'/>
The custom sType project/asset is view-only and not editable by a particular group.
<rule group='sobject' search_type='project/asset' access='view'/>
The custom sType project/asset is not viewable by a particular group. The search result will always come up empty.
<rule group='sobject' search_type='project/asset' access='deny'/>
Search Filter Examples
To enforce what can be searched or filtered out in any situation like script query or UI view, search_filter rules can be applied. The access attribute is not required here.
This rule filters out tasks belonging to project "pacman" and "sample3d". Notice you don’t need "access" here.
<rule group='search_filter' column='project_code' value='pacman' op='!=' search_type='sthpw/task' /> <rule group='search_filter' column='project_code' value='sample3d' op='!=' search_type='sthpw/task' />
This rule retrieves task that is assigned to the current login user, applicable when navigating in project sample3d. Notice the value attribute can accept an expression. $LOGIN and $PROJECT are also supported.
<rule column='assigned' value='@GET(login.login)' search_type='sthpw/task' op='=' group='search_filter' project='sample3d'/> or <rule column='assigned' value='$LOGIN' search_type='sthpw/task' op='=' group='search_filter' project='sample3d'/>
Miscellaneous Examples
This rule blocks a user from seeing the options "Approved" and "Complete" in the task status drop-down
<rule access='deny' key='Complete' category='process_select'/> <rule access='deny' key='Approved' category='process_select'/>
Security Version 2
The following are examples of how to fine tune control access to TACTIC in security version 2. (Some of these example may be repeated in security version 1 above.)
Project Access:
This allows the group to see the project with the code "toy_factory".
<rules> </rules>
Link Access:
This allows the group to see the link named "block_set_list" in the project named "toy_factory".
<rules> <rule group="project" code="toy_factory" access="allow"/> </rules>
sType (Search Type) Access:
This allows the group
to see the sType "toy_factory/design" in the project named "toy_factory".
to hide the sType "sthpw/task" in the project named "toy_factory".
<rules> <rule group="project" code="toy_factory" access="allow"/> <rule group="link" element="block_set_list" project="toy_factory" access="allow"/> </rules>
Process Access:
This allows the group to see the process named "packaging" in the project named "toy_factory".
<rules> <rule group="project" code="toy_factory" access="allow"/> <rule group="link" element="block_set_list" project="toy_factory" access="allow"/> <rule group="search_type" code="toy_factory/design" project="toy_factory" access="allow"/> <rule group="search_type" code="sthpw/task" project="toy_factory" access="deny"/> </rules>
User Interface Column level Access:
This allows the group to:
-view the element description
-edit the element name
<rules> <rule group="project" code="toy_factory" access="allow"/> <rule group="link" element="block_set_list" project="toy_factory" access="allow"/> <rule group="search_type" code="toy_factory/design" project="toy_factory" access="allow"/> <rule group="search_type" code="sthpw/task" project="toy_factory" access="deny"/> <rule group="process" process="packaging" project="toy_factory" access="allow"/> </rules>
There is no user interface in TACTIC to remove a project. This is because the complete removal of a project has some pretty significant consequences. When a project is created, a number of elements are created. These are listed below.
Note
This task may need to be carried out by the Tactic System Admin as it involves manually accessing both the Tactic File system and the Tactic Database
In all of the following examples, <project_code> represents the code of the project when the project was created.
A complete removal of a project should be handled with care. This is most often desirably when a project has been created in properly. It is one of the few operations that is not undo-able in TACTIC, so it is recommended to be careful when proceeding with the following steps. It is also recommended that a complete backup of TACTIC is performed before carrying out this process.
Remove the project directory
cd <project_install_dir>/sites rm -rf <project_code>
Remove the database
psql -U postgres sthpw drop database "<project_code>";
Remove the assets directory
cd <project_asset_dir> rm -rf <project_code>
Remove the entry in the projects table in the database
psql -U postgres sthpw delete from project where code='<project_code>';
Remove connected entities in the sthpw database;
In this process, Tactic may not allow removing a particular project due to there being child tasks, notes, snapshots, files, wdg_settings etc. If Tactic denies revoval because, for example there is a connection in the file table, you will need to do the following
delete from file where project_code='<project_code>'; delete from snapshot where project_code='<project_code>'; delete from task where project_code='<project_code>'; delete from note where project_code='<project_code>'; delete from wdg_settings where project_code='<project_code>'; delete from pref_setting where project_code='<project_code>';
The TACTIC Event System is built into the base transactional system in Tactic’s core. Every transaction which occurs in Tactic can fire an event which in turn, can be used to execute a trigger or notification.
These events can be incorporated to automate specific processes that are often repetitive. At the simplest level, there are interfaces that help prepare and configure these aspects but, it is good to understand how they work. Overall, there are 2 levels that these events can be configured. The first is using the predefined event options provided in the Project Workflow or Project Schema interfaces and the second in the low level database events.
Predefined Events
The following list of events are the events provided in the Project Workflow interface. For more information in setting up Notifications and Triggers with this interface, please refer to Project Automation - Triggers and Project Automation - Notifications
A task Status is Changed | When the status of a task is changed. Further options are provided allowing for selection. |
A new note is added | When a new note (sthpw/note) is added to the project. |
A task is assigned | When a task is assigned to a user. |
Files are checked in | When files are checked in to an SObject. |
Files are checked out | When files are checked out from an SObject. |
Custom event | Allows for calling of an event using the raw Database Events. |
Raw Database Events
Below is the list of the database level events. These events are run regardless of how they are called (interface, api, external integration etc)
done | Executed each time a transaction completes |
insert | Executed each time a Search Object has been inserted. |
update | Executed each time a Search Object has been updated. |
change | Executed each time a Search Object has changed. This combines the events insert, update and delete. |
retire | Executed each time a Search Object has been retired. |
delete | Executed each time a Search Object has been deleted. |
checkin | Executed each time a checkin occurs for a Search Object |
checkout | Executed each time a checkout occurs for a Search Object |
timed | Executed on a timed interval. This is only supported for triggers. |
For example, in a transaction where the status of a task is being changed, an association to this event can be made with the following notation:
update|sthpw/task|assigned
The notation can consist of 3 sections although only the event is required.
<Event>|<SType>|<Column>
Event | The raw database event. |
SType | The Searchable Type (SType) the event is occurring for. |
Column | The Column that was changed in the SType. |
Triggers are events that are called upon a transaction to automate workflow. These triggers can be accessed within the Project Workflow view.
Admin Viwes → Project Admin → Project Workflow
Each process in the pipeline can have their own triggers. Right clicking on a process and choosing show notification/trigger option will open a tab to define a trigger for that specific process.
The trigger tab will also display the assigned process. Clicking the insert button will open the trigger UI.
Title | Title of the trigger. |
Description | Description of the trigger. |
Unique Code | [multiblock cell omitted] |
Event | Drop down list of trigger events. This event is where the trigger is called. |
Action | The action is what the event will |
EVENT
The Events drop down list provides a wide range of different triggers.
Depending on the trigger the Event box may show additional options.
A new note is added - This Event will be called when a new note is inserted into the process.
A task status is changed - This event will be called when a status is changed. The event box also gives a additional option to choose specific status.
A task is assigned - This event will be called when any task in the specified process is assigned.
Files are checked in - This event will be called when there is a checkin to the specified trigger. This event also gives a additional option to choose what process the action will effect.
Files are checked out- This event will be called when there is a checkout to the specified trigger.
Cusom Event -
ACTION
The Action drop down list provides a series of predifined actions that work with the above events.
Send a notification - See project automation notification docs.
Update another task status - This action will update a task status. This action also opens additional options to update status of current and other process of the pipeline as well as the option of status.
Create another task - This Action will create a task upon event. This action also opens additional options to choose from creating a task in current or next process.
Run python code - This Action will run python code upon event. The action box opens additional options to name and insert a python code.
Run python trigger - This Action will run python trigger upon event. The action box opens additional option to insert the name of the trigger. These can be custom written scripts that can be called from Tactic’s API.
When satisfied with the options set to run a trigger, the trigger must be saved in order to be applied. When the trigger is saved the title of the trigger will appear benieth the triggers panel.
There are no limitations of how many triggers you can have. Each process can have multiple triggers applied.
Description
Notifications are sent to inform the user that a particular transaction or event has occurred.
They are stored in a notification_log which can be found under Admin Views → Site Admin → Notifications.
Notifications.
Notifications present information reported by transactions. They usually include what items are created or updated in addition to a description of the command. Below is an example of a notification:
With the mail server setting set up properly (set in the TACTIC Config file), TACTIC can send out email notifications to users.
Implementation
There are 2 perspectives to work from when configuring notifications in TACTIC.
Project Workflow
In the Workflow Editor, right click on a process and choose show notification/trigger to open a tab to define a trigger for that particular process.
This will open a new Triggers tab in the panel at the bottom for the assigned process.
Click the [+] button to insert a trigger. This will open the trigger/notification UI.
Notifications and Triggers work together in many ways. A notification is defined as an Action. To send a notification, an event must occur.
In the Action drop down list Send a Notification must be selected.
Send a Notification - This action will send a notification. The action box will open additional options to insert a subject and message.
Below is an example of a notification being sent on the event when a task status is changed to review:
The Mail To: and Mail CC: input fields accepts the following types of input:
Email - Capability to add regular emails allows to send personal email addresses e.g. joe@my_email.com
Group - Capabilty to send to a group of users in TACTIC e.g. Supervisor
Expression - Capabilty to insert expressions that specifies a user in TACTIC. All expressions are identified by curly brackets "{}". e.g. {@SOBJECT(sthpw/login)}
Send a Notification - This action will send a notification. The action box will open additional options to insert a subject and message.
Below is an example which uses more expressions for a notification being sent whenever a task is assigned.
Project Schema
All notification configurations can be accessed through Admin Views → Site Admin→ Notifications
If there is no process specified, then the notification will be triggered regardless of process. e.g. during a snapshot or a checkin
The notification view is located in the TACTIC Sidebar under:
Site Admin → Notifications
This can also be accessed through the Workflow Editor, by right clicking on a node and selecting from the context menu Show Triggers/Notifications.
This view provides all the functionality required to set up the various types of notifications used to establish better production communication and instant status updates.
Insert Notifications
To insert a new notification, select from the sidebar:
Site Admin → Notifications
The following table explains the basic usage of each property.
Event | The TACTIC event to execute the notification for |
Project Code | The project code for the notification. This allows for filtering of notifications for a specific project |
Type | The type of notification being sent. By default for notifications, this must be set to "email" |
Search Type | The search type attribute identifies the parent sType if the event is for a task, note, or snapshot. It used to be achived by adding a rule as in Example 2. |
Mail_to | An expression of the users to mail to in the email (supports multiple lines of expressions and / or email addresses and names of groups of users made in TACTIC) |
Mail_cc | An expression of the users to mail to in the email. It will appear in the cc category. (supports multiple lines of expressions and / or email addresses and groups) |
Mail_bcc | An expression of the users to mail to in the email. It will appear in the bcc category. (supports multiple lines of expressions and / or email addresses and groups) |
Note: The default is to email the person that causes the notification to fire through the event set up. To turn off this behavior, you can add an entry in Project Setting: key = email_to_sender , value = false.
Below are examples of what can be used in mail_to, mail_cc, or mail_bcc:
For example, email the user admin only:
@SOBJECT(sthpw/login['login', 'admin'])
For example, send to the user related to this sObject. If this is an event for task update, the email will be addressed to the assigned user:
@SOBJECT(sobject.sthpw/login)
If it is already a task for the event update|sthpw/task, which contains the assigned or supervisor attribute, the email will be addressed to both by just retrieving these attributes in two lines.
@GET(sobject.assigned) @GET(sobject.supervisor)
Let’s say you want something simpler and skip the use of task. If you have an sType called mystuff/manager that already contains an email address or comma separated email addresses in an attribute called email, you may want to email to the dedicated manager for a paricular shot. Assuming your shot sType mystuff/shot and mystuff/manager has a schema connection already, you can email them when updating your shot with the event update|mystuff/shot.
@GET(sobject.mystuff/manager.email)
If you want to email to the same manager David and a person named Carin defined in Users when updating any shots with the event update|mystuff/shot, there is no need to start off with the variable sobject representing the shot in transaction.
@GET(mystuff/manager['first_name']['David'].email) @GET(sthpw/login['first_name']['Carin'].email)
For example, send to the user related to this sObject as well as the user john. If the event is insert|sthpw/note, it will be the person who enters the note. If the event is update|sthpw/task, the person is the assignee of the task:
@UNION(@SOBJECT(sthpw/login['login', 'john']), @SOBJECT(sobject.sthpw/login))
To make these mail_to expressions more readable, put more than 1 expression or email addresses on multiple lines. There is no need for @UNION. @GET can even be used to just get to the list of login names.
For example, to send to everyone in the supervisor group, the assignee of a task, to all the users in the mangers group and the email address support@southpawtech.com, enter 3 lines under mail_to:
@SOBJECT(sobject.sthpw/login) @GET(sthpw/login_in_group['login_group','supervisor'].login) managers support@southpawtech.com
More on Expressions in Notifications
The word "sobject" often appears in the Mail to: column but not in Message or Subject. This is because the implementation allows sending notifications to users related to the current sObject or just about anyone not necessarily related to the current sObject. As illustrated above, @SOBJECT(sobject.sthpw/login) is the task assignee but the users under the group supervisor is not related to this task and so the keyword "sobject" is not used. In the Message area, to refer to the current sObject status (task status if the event is update|sthpw/task), just use an @GET(.status), as the sobject is always assumed to be in this context.
Task related notification
To establish the relationship between the login search type and task search type, the following built-in schema line is used. It is not necessary to add it to the schema. It can be used as an example to create a custom search_type.
<connect to='sthpw/task' relationship='code' from_col='login' from='sthpw/login' to_col='assigned'/>
Note related notification
To establish the relationship between the login search type and note search type, the following built-in schema line is used. It is not necessary to add it to the schema. It can be used as an example to create a custom search_type and to edit the schema.
<connect to='sthpw/note' relationship='code' from_col='login' from='sthpw/login' to_col='login'/>
Sending a notification to the person who just entered the note is not often used. Instead, an email handler can be used in this situation to send to the supervisor and assignee of the task under the same context. A built-in email handler is called "pyasm.command.NoteEmailHandler". Instead of entering it into an expression for mail_to, enter it into the email_handler_class field.
Email Test
Once the fields event, mail_to, and message are properly filled in, to test the email, click on the Email Test button. It catches syntax errors or typos in expression in these fields as well as reporting any email server error if the service section of the TACTIC config file has not been properly filled in. Settings like firewall and TLS settings may also block an email from being sent out.
Example 1:
In this example, the notification will be sent out each time a ticket is updated. It will also only send to users in the admin and moderator groups.
Event | update|support/ticket |
Description | Sent when tickets are updated |
Subject | |
Message | [multiblock cell omitted] |
mail_to | admin , user@gmail |
Rules | [multiblock cell omitted] |
Email Handler Class | [multiblock cell omitted] |
Project Code | support |
Type |
Example 2:
In this example, the notification will be sent out each time a shot-based note is updated. It will send to manager’s group and everyone assigned to the tasks of the shot. Since project_code is left empty, this works across all the projects in the system.
Event | insert|sthpw/note |
Description | Sent when shot-based notes are added |
Subject | {$PROJECT} {@GET(parent.sequence_code)} - {@GET(parent.code)} {@GET(.process)} |
Message | |
Rules | |
Email Handler Class | [multiblock cell omitted] |
Project Code | [multiblock cell omitted] |
Type | |
mail_to |
Example 3:
In this example, the notification will be sent out each time a note is added. It also allows users to have their own Email Message Template and preserve its html format.
Event | insert|sthpw/note |
Description | Sent when new note is added |
Subject | TACTIC: a new note has been added. |
Message | |
Rules | [multiblock cell omitted] |
Email Handler Class | [multiblock cell omitted] |
Project Code | [multiblock cell omitted] |
Type | |
mail_to | admin, user@gmail.com |
Notification Expressions
TACTIC uses the TACTIC Expression Language to build dynamic Notification Subject and Message contents. This allows for each notification to be sent based on properties from the Search Objects it is being sent for.
In the simple example Subject below, the "id" property is used from the "ticket" search object.
TACTIC Ticket {$GET(.id)} has been updated
The expected results of this would be similar to the following:
"TACTIC Ticket 14 has been updated"
Example 1
In essence, anything between the curly brackets "{}" is evaluated as an expression by TACTIC.
Note
For more information regarding TACTIC Expression Language please refer to the TACTIC Expression Language docs
Filtering Notifications
TACTIC’s notification architecture is a rules-based system built using the trigger architecture. Every time a command is executed, TACTIC looks through the list of defined triggers (including notifications) for a match. Under the Triggers view will be an entry for the EmailTrigger class that is registered under the "email" event. It is possible to create custom Email Trigger handlers in that view.
There are 3 main criteria used to filter out notifications:
Groups
By planning groups to send notifications to, it allows for simple connections for deciphering which groups of users will receive notifications when the conditions of a particular notification rule are met. Once a notification has been created, it can be associated with any number of groups of users. All users in this group will then be sent a notification when the rule is triggered.
The Groups view can be found under:
Admin→Site Admin →Groups
To specify a group to send a notification to, specify the group in the mail_to column.
Project
By setting the project in the project column of a Notification, TACTIC will only use the notification trigger for the chosen project.
Access Rules
When a notification rule has passed all of the criteria, a message is constructed. Most email events occur after a command has been completed. The email handler then takes the information from the command and creates a default message to be sent to the appropriate people.
All rules are contained in groups. For notifications, there are a few predefined groups:
Example 1
This rule group only allows tasks for prod/asset for the project sample3d to send out notification. Otherwise, it would send out notifications for tasks of all search types
<rules> <rule>@GET(.search_type)=='prod/asset?project=sample3d'</rule> </rules>
Example 2
This rule group makes use of a key/value pair of attributes: that is, when the attribute with the value of "key" is equal to "value", the rule is passed. In the example below, all SObjects containing the attribute "context" with the value "client" are triggered.
(deprecated) <rules> <rule group="SObject" key="context" value="client"/> </rules>
<rules> <rule>@GET(.context)=='client'</rule> </rules>
Example 3
For certain SObjects in TACTIC (like tasks), parent attributes can be used for constructing rules. The concept behind this is the same as group="sObject", but now we are referring to the parent of a task (for example, a 3D asset). This notification will only be sent if the task’s parent, a 3D asset, is categorized under the "prp" asset library.
<!-- DEPRICATED --> <rules> <rule group='parent' key='asset_library' value='prp'/> </rules>
<rules> <rule>@GET(prod/asset.asset_library)=='prp'<rule> </rules>
Example 4
For notes in TACTIC, we may have 2 processes for notes (e.g. anim, anim_2) We can check if the process partially contains the word anim by the following:
<rules> <rule>'anim' in @GET(.process)<rule> </rules>
Note: list comparisons like @GET(.process) in [anim,anim_2] are not supported
Example 5
For a check-in notification in TACTIC, we can choose to send only if the is_current attribute is True for the event insert|sthpw/snapshot by the following:
<rules> <rule>@GET(.is_current)==True<rule> </rules>
Email Handler Class
Each time a notification is executed, TACITC uses either the default email handler or it uses and email handler override defined by the Email Handler Class property for the notification.
The Email Handler Class digs deeply into the structure of the notifications using Python and the TACTIC client API. It is only needed for very specific rules which determine when a notification is sent.
An example override is shown below:
Email Hander Cls: sites.support.email.TicketEmailHandler
__all__ = ['TicketEmailHandler'] from pyasm.common import Environment, Xml, Date from pyasm.security import Login from pyasm.search import Search from pyasm.biz import GroupNotification, Pipeline, Task, Snapshot, File, Note class TicketEmailHandler(object): '''Email sent when a ticket is updated''' def __init__(my, notification, SObject, parent, command): my.notification = notification my.sobject = SObject my.command = command my.parent = parent def check_rule(my): '''determine whether an email should be sent''' return True def get_to(my): ticket = my.sobject user = ticket.get_value("login") login = Login.get_by_login(user) recipients = [] recipients.append(login) return recipients def get_cc(my): admin = Login.get_by_login("admin") recipients = [] recipients.append(admin) return recipients def get_subject(my): ticket = my.sobject title = "Ticket Number: " id = ticket.get_value("id") return "%s%s" % (title, id) def get_message(my): ticket = my.sobject id = ticket.get_value("id") subject = ticket.get_value("subject") summary = ticket.get_value("summary") status = ticket.get_value("status") msg = [] msg.append("Ticket: %s" % id) msg.append("") msg.append("Status: %s" % status) msg.append("") msg.append("subject: %s" % subject) msg.append("Summary: %s" % summary) msg.append("") return "\n".join(msg)
-include::../section/doc/tactic-setup/setup/advanced-event-usage/index.txt[]
-include::../section/doc/tactic-setup/setup/advanced-trigger-setup/index.txt[]
-include::../section/doc/tactic-setup/setup/advanced-file-naming-setup/index.txt[]
-include::../section/doc/tactic-setup/setup/versionless-checkin/index.txt[]
TACTIC Expression Language Introduction
Introduction
This document describes the construct of the TEL TACTIC Expression Language. This language is a shorthand form to quickly retrieve information about related Search Objects. The expression either starts with a list of Search Objects and the operations of the expression language operate on these lists (this is quite similar to LISP in concept) or it can be used as an absolute search.
The expression language also borrows from spreadsheet syntax which is familiar to many people. The reason behind using an expression language is that it is much simpler and compact that using code or direct SQL. The TACTIC expression language is designed to be able to easily retrieve data in a single command that would otherwise take many lines of code.
Simple Example
The expression often starts with a list of Search Objects and then operates on these Search Objects.
If you have a list of "prod/sequence" Search Objects, then the following:
@GET(prod/shot.code)
will return a list of codes of these prod/shot Search Objects related to the starting "prod/sequence". The notation for the method GET is of the form <search_type>.<column>. As will be shown below, multiple search_types can be strung together to navigate across related search_types. The @GET function operate on a list and returned a list.
If no starting sObject is given, this expression will return a list of codes for every shot in the project. In the python or javascript API, you can control whether there is a starting sobject with the kwarg search_keys
With the above example, here is how to get the shot codes for the given sequence with the code "seq001":
Python API
server = TacticServerStub.get()
expr = "@GET(prod/shot.code)"
result = server.eval(expr, search_keys=[prod/sequence?project=vfx&code=seq001])
By default, the result returned is a list unless you specify the kwarg single=True in server.eval()
result = server.eval(expr, search_keys=[prod/sequence?project=vfx&code=seq001], single=True)
In Javascript, via the Script Edtor, you can achieve the same result with these scripts:
Javascript API
var server = TacticServerStub.get();
var expr = "@GET(prod/shot.code)"
var result = server.eval(expr, {search_keys: [prod/sequence?project=vfx&code=seq001], single: true});
In certain places, like in a Custom Layout Element, Expression Element in a Table, or notification set-up, there is an assumed starting sObject, which is the one you are viewing or the notification event refers to during an update or insert action.
Searching
The expression language can be used as a shorthand for search for Search Objects. This is often convenient because the expression language is a pure string and can be stored a number of formats, including XML.
The @SOBJECT method will retrieve entire Search Objects.
Search for all assets
@SOBJECT(prod/asset)
Search only for characters by applying a filter
@SOBJECT(prod/asset['asset_library','chr']
You can also apply multiple filters. And operation is implied
@SOBJECT(prod/asset['asset_library','chr']['timestamp','>','2009-01-01'])
You can also apply multiple filters. To use OR operation with more than 2 filters. For example, with code containing the word prop1, OR asset_library is chr, OR timestamp after 2009-01-01. Note: EQ stands for case-sensitive match.
@SOBJECT(prod/asset['begin']['asset_library','chr']['timestamp','>','2009-01-01']['code','EQ','prop1']['or'])
To use OR operation with 2 filters followed by an AND operation. For example, with asset_library is chr OR timestamp after 2009-01-01 AND code containing the word prop1. If there are only 2 filters, there is no need to sandwich it with begin.
@SOBJECT(prod/asset['begin']['asset_library','chr']['timestamp','>','2009-01-01']['or']['code','EQ','prop1'])
To
@SOBJECT(prod/asset['begin']['asset_library','chr']['timestamp','>','2009-01-01']['or']['code','EQ','prop1'])
Note that full filter operations from the Client API are supported.
Navigating Search Types
One of the true powers of the expression language is the simplicity in which it can navigate between various related Search Types using a navigational syntax. The expression language makes use of the project schema to navigate dependencies between the search_types. For example a sequence is related to a shot.
The navigational syntax is used as arguments for many aggregate methods. When detected, the expression language will perform a search through the hierarchy to retrieve the desired search results.
A simple example of the navigation syntax in the expression language is as follows:
@GET(prod/sequence.code)
This expression will get all of the codes of the sequences of related to each Search Object.
The expression can also navigate multiple levels of search types to dig deeply into the hierarchy. For example, this will get all of the descriptions of all of the episodes that belong to the sequences of the original shots.
@GET(prod/sequence.prod/episode.description)
Another useful illustration is to get all of the tasks of all of the shots:
@SOBJECT(prod/shot.sthpw/task)
Get the last 50 tasks ordered by process of all of the shots:
@SOBJECT(prod/shot.sthpw/task['@ORDER_BY','process']['@LIMIT','50'])
Aggregate functions
The expression language defines a number of aggregate functions which will operate on the list.
This will give the addition of all the duration attributes of the provided shots.
@SUM(prod/shot.duration)
This will give the average duration attribute of all of the shots.
@AVG(prod/shot.duration)
This will give a count of all of the Search Objects
@COUNT(prod/shot)
All of these aggregates return a single value which can be used to operate on other lists.
Operations
The expression language operates on lists. The operator will operate on each element of the list independently and return a list For example when doing a subtraction operation on items:
@GET(prod/shot.end_frame) - @GET(prod/shot.start_frame)
The first @GET will return a list of start frames and the second @GET will return a list end frames. When two lists are operated on the results are calculated based on items at the same position in each list. So if we had two lists:
[300, 155, 100] - [100, 100, 100] = [200, 55, 0]
Similarly, lists will be multiplied as follows
[5, 4, 3] * [5, 4, 3] = [25, 16, 9]
The expression language supports most operation support by the python language itself.
>>> Search.eval("5 * 25") 125.0 >>> Search.eval("5 + 25") 30.0 >>> Search.eval("(25 - 5) * 5") 100.0 >>> Search.eval("5 / 25") 0.20000000000000001 >>> Search.eval("@COUNT(sthpw/task) * 5") 2310.0 >>> Search.eval("@COUNT(sthpw/task) > 0") True >>> Search.eval("@COUNT(sthpw/task) == 462") True >>> Search.eval("@COUNT(sthpw/task) != 462") False
The expression language also supports the regular expression syntax
The following tests whether the name_first column starts with "John"
@GET(.name_first) ~ '^John'
More complex operations
You can do more complex operations by combining the above. The following will return a cost list of all of the shots (assigned user wage * number of hours worked).
@GET(prod/shot.sthpw/task.sthpw/login.wage) * @GET(prod/shot.num_hours)
You could add them all together using @SUM this to get the total
@SUM( @GET(prod/shot.sthpw/task.sthpw/login.wage) * @GET(prod/shot.num_hours) )
There are times the sObjects returned are not unique. The @UNIQUE operator can be used to return a unique list of result. The following returns the unique list of login sObjects related to the task list provided. The @COUNT operator computes the total number of login sObjects.
# my.tasks is a list of tasks expression = "@COUNT(@UNIQUE(@SOBJECT(sthpw/login)))" result = my.parser.eval(expression, my.tasks)
Manipulating Strings
Most of the operations in the expression language operate on lists and either return lists or return single values. However, it is often required that expressions be used in string concatenation. A simplified notation is to use curly brackets {} to represent an operation that converts the result of an expression into a string.
For a file to be named chr001_model.png, we could use:
{@GET(prod/asset.code)}_{@GET(sthpw/snapshot.context)}.png
String Formatting
For string values, the string operator them can use standard print formatting:
v{@GET(sthpw/snapshot.version),%0.3d}
will return "v012", for example.
The expression language also supports formatting through regular expressions
{ @GET(prod/asset.description),|^(\w{5})| }
This will get the first 5 word characters for the description. Since the full expression language is supported, it is possible to extract a wide variety of parts. Anything matched with () will be returned as the value.
**If there are multiple groupings, the expression language will concatenate the values together.
The following will return the first 3 and last 3 characters of the description.
{ @GET(prod/asset.description),|^(\w{3}).*(\w{3})$| }
The following will return the last 5 characters of the description of the current SObject even if it is written in French or Chinese.
{ @GET(.description),|^(.{5})$| }
Time related formatting
The following formats a timestamp by extracting just the month and date (old way):
{ @GET(.timestamp), %b-%m}
The following formats a timestamp by extracting just the year
{ @GET(.timestamp), %Y}
The following removes the hours, minutes and seconds from the built-in $TODAY variable so only 2011-11-11 is displayed
{ $TODAY,|([^\s]+)| }
The following formats a timestamp by using the new @FORMAT function
@FORMAT( @GET(.timestamp), '31/12/1999')
@FORMAT( @GET(.timestamp), 'Dec 31, 1999')
The following formats it according to a project wide date-time setting or date-only setting. You can define what DATETIME and DATE is in the Project Settings page.
@FORMAT( @GET(.timestamp), 'DATETIME') @FORMAT( @GET(.timestamp), 'DATE')
Either of the following formats a frame count into timecode
@FORMAT( @GET(.frame_count), 'MM:SS.FF')
The following formats a frame count into hours, minutes and seconds in 30fps, leaving out the frames.
@FORMAT( @GET(.frame_count), 'HH:MM:SS', '30')
The following formats a cost column in currency format
@FORMAT(@GET(.cost), '-$1,234.00')
31/12/99 13:37 can be used to show both date and time
Shorthand (mostly for backwards compatibility)
@GET(sobject.end_frame) - @GET(sobject.start_frame) or @GET(.end_frame) - @GET(.start_frame)
Or replicate file naming conventions
{sobject.code}_{snapshot.context}_v{version}.{ext}
In the file naming convention language, the are a number of short hand keywords:
sObject Keywords: sobject, snapshot, file, parent , search_type
Attribute Keywords: context, version, ext, basefile
Expression Method Reference
GET
@GET( [search]:nav )
v2.5.0+
The GET method will retrieve attributes or columns from a list of SObjects. This method returns a list of the values. The first argument supports the search type navigational syntax to travel through related search types.
Get the bid start date of all of the tasks:
@GET(sthpw/task.bid_start_date)
Get the assigned user of all of the modelling tasks
@GET(sthpw/task['process','model'].assigned)
Get the assigned user of all of the modelling , anim, OR lighting tasks
@GET(sthpw/task['begin']['process','model']['process','anim']['process','lgt']['or'].assigned)
The GET function also supports short hand to get all attributes from the current SObjects. This will get the assigned column for all current SObjects
@GET(.assigned)
GETALL
@GETALL( [search]:nav )
v4.1.0+
The GETALL method works in a similar way to GET; this method also returns a list of the values. Both work identically if the expression given is as simple as (sthpw/login.id). The difference lies in more complex queries:
@GETALL(sthpw/task.sthpw/login.first_name)
The above query returns the name of the user associated with each task. Unlike GET, GETALL will show each user’s name for as many tasks as they are associated with. GET does not display any duplicates.
Example use of GETALL:
@SUM(@GETALL(sthpw/task.sthpw/work_hour.sthpw/login.hourly_wage) * @GETALL(sthpw/task.sthpw/work_hour.straight_time))
This example retursns the total cost of a task based on the hours logged and the hourly wage of each employee.
SOBJECT
v2.5.0+
The SOBJECT method is similar to the GET SObject except that the entire search object is retrieved.
The following expression gets all of the completed modelling tasks.
@SOBJECT(sthpw/task['status','complete']['process','model'])
The following expression gets all of the completed tasks OR model tasks.
@SOBJECT(sthpw/task['begin']['status','complete']['process','model']['or'])
The following expression deals with time related attribute. Get the tasks where the bid_end_date is before 2012-02-10 and after 2013-01-08
@SOBJECT(sthpw/task['begin']['bid_end_date','is before','2012-02-10']['bid_end_date','is after','2013-01-08']['or'])
The following expression deals with numbers. You can use >, < , >=,or ⇐.
@SOBJECT(sthpw/task['priority','>=','3'])
The following expression deals with containing a word. You can use EQ, EQI, like. EQ and EQI (case-insensitive) makes use of regular expression engine of the database if available. With "like", you have to make use of the % wildcard
@SOBJECT(sthpw/task['description','like','%rock%'])
@SOBJECT(sthpw/task['description','EQ','rock'])
The following expression deals with NOT containing a word. You can use NEQ, NEQI, not like. NEQ makes use of regular expression engine of the database if available. With "not like", you have to make use of the % wildcard
@SOBJECT(sthpw/task['description','not like','%rock%'])
@SOBJECT(sthpw/task['description','NEQ','rock'])
The SOBJECT method can also traverse thru related sTypes if their relation has been set up in the Project Schema.
The following expression gets all the shots for sequence SE02 and SE03:
@SOBJECT(prod/sequence['code','in','SE02|SE03').prod/shot)
Certain relationships like those between anything to notes or tasks are already pre-established.
The following expression gets all the shots that have a note starting with the word Hello:
@SOBJECT(sthpw/note['note','EQ','^Hello').prod/shot)
COUNT
v2.5.0+
The COUNT method will return the count of the SObject returned by the search specifications.
To get a count of all the tasks:
@COUNT(sthpw/task)
To get a count of all the tasks of all of the shots:
@COUNT(prod/shot.sthpw/task)
To get a count of all the modelling tasks of all of the completed shots
@COUNT(prod/shot['status','complete'].sthpw/task['context','model'])
SUM
v2.5.0+
This method will calculate a sum of all of the values in the first argument. The first argument must conform to the navigational syntax.
AVG
v2.5.0+
Calculates the average of all of the values of the first argument, which must conform to the navigational syntax.
MIN
v2.5.0+
Returns the minimum value in a list
MAX
v2.5.0+
Returns the maximum value in a list
FLOOR
v2.5.0+
Returns the lowest integer value of a passed in value
UNIQUE
@UNIQUE( [expr1]:expr )
v2.5.0+
The UNIQUE method goes through a list returned from an expression and ensures that only unique elements are present. Duplicates are discarded
UNION
@UNION( [expr1]:expr, [expr2]:expr, … )
v2.5.0+
The UNION method combines the union of all of the results from a number of expressions together into a single list.
Combine all the users from accounting and marketing together into one list:
@UNION( @SOBJECT(sthpw/login['dept','accounting'], @SOBJECT(sthpw/login['dept','marketing'] )
INTERSECT
@INTERSECT( [expr1]:expr, [expr2]:expr )
v2.5.0+
The INTERSECT method takes the intersection of all the results of expressions in the arguments.
@INTERSECT( @GET(sthpw/login['dept','supervisor']), @GET(sthpw/login['dept','director']) )
IF
@IF( [condition]:expr, [if_true]:expr, [if_false]:expr )
v2.6.0+
The following example will return red if the number of tasks is greater than 5 and green if less than or equal to 5. These types of expressions are very useful to determine colors of various backgrounds or widgets within TACTIC.
@IF( @COUNT(sthpw/task) > 5, 'red', 'green') )
Not all of the arguments can be expressions, so the values for both is_true and is_false can be expressions that are evaluated:
@IF( @COUNT(sthpw/task) > 5, @GET(.color1), @GET(.color2) ) )
CASE
@CASE( [condition1]:expr, [if_true]:expr, [condition2:expr], [if_true]:expr, … )
v2.6.0+
The case statement is an extension of the IF method, but it allows any number of arguments. The odd arguments are conditional tests which must evaluate to True or False. The case method will go through each of the odd arguments until one of the evaluates to True at which point it will evaluate the corresponding even argument and return that value.
@CASE( @GET(.age) < 10, 'blue', @GET(.age) < 20, 'green', @GET(.age) < 30, 'yellow', @GET(.age) >= 30, 'red' )
FOREACH
v2.6.0+
The following expression gets all the first name from the login table as a list. and then loop through and add <li> </li> around each item. This is more suited in situation where you don’t much control over the data returned like in a CustomLayoutWdg:
@FOREACH( @GET(sthpw/login.first_name), '<li>%s</li>' )
JOIN
@JOIN( [expr]:expression, [delimiter]:literal
v2.6.0+
The join method take the result of an expression and joins all the elements together using a delimiter
UPDATE
@UPDATE( [expr1]:expression, [column]:string, [value]:expression )
v2.6.0+
The UPDATE method provides the ability for an expression to update a value in the database
The following example updates all of the modelling task to approved
@UPDATE( @SOBJECT(sthpw/task['context','model']), 'status', 'Approved' )
You can display a model task status column in the Asset page and any other asset related pages and have them all pointing back to the task search type during an update. It would eliminate any redundant data. The following xml definition can be used to set this up in the asset page for instance:
<element edit='true' name='asset_task_status' title='Task Status'> <display widget='expression'> <expression>@GET(sthpw/task['context','model'].status)</expression> </display> <action class='DatabaseAction'> <expression>@UPDATE(@SOBJECT(sthpw/task['context','model']), 'status', $VALUE) </expression> </action> </element>
The edit view for the Widget Config of prod/asset needs to contain this snippet to display the selection list of different statuses
<element name='asset_task_status'> <display class='tactic.ui.widget.TaskStatusSelectWdg'/> </element>
EVAL
@EVAL( [expr1]:expression )
@( [expr1]:expression )
v2.6.0+
PYTHON
v3.9.0+
It takes one argument, the script path of a script you have defined in the TACTIC Script Editor. For instance, to draw the bid_start_date and bid_end_date of some specific related tasks when the user changes an attribute of a shot, you can define a script called notification/dates and use this expression in the message field of notification.
@PYTHON(notification/dates)
# notification message displaying shoot schedule from pyasm.search import Search expr = "@SOBJECT(sthpw/task['context','minor'])" tasks = Search.eval(expr, sobjects=[sobject]) dates = [] for task in tasks: # assuming they are on the same day day_expr = "@FORMAT(@GET(.bid_start_date),'1999-12-31')" time_expr1 = "@FORMAT(@GET(.bid_start_date),'01:37 PM')" time_expr2 = "@FORMAT(@GET(.bid_end_date),'01:37 PM')" day_val= Search.eval(day_expr, sobjects=[task], single=True) time_val1= Search.eval(time_expr1, sobjects=[task], single=True) time_val2= Search.eval(time_expr2, sobjects=[task], single=True) schedule = '%s %s - %s' %(day_val, time_val1, time_val2) dates.append(schedule) return ''' '''.join(dates)
COLOR
@COLOR(attribute[,offset])
v4.1.0+
Returns the current palette’s color for the chosen attribute plus an offset. Offset is a number that can be used to make the color lighter or darker. The attribute can also be a hex value.
Ex: @COLOR(color2, 2) will return the second color for this palette.
GRADIENT
@GRADIENT(attribute[,offset,gradient_range])
v4.1.0+
Returns a CSS gradient value that starts at the attribute + offset and transitions to attribute + offset + gradient_range.
Ex: "@GRADIENT(#777777,3,-4)" will return \[-webkit-gradient(linear, 0% 0%, 0% 100%, from(#7e7e7e), to(#747474))]
PALETTE
@PALETTE([palette_name])
v4.1.0+
Returns a dictionary representing the current palette or a specific palette if the optional argument palette_name is included.
Example return value:
{color: #000, background2: #777777, color3: #333, color2: #333, background: #DDDDDD, shadow: rgba(0,0,0,0.6), border: #888888, table_border: #DDD, background3: #999999, side_bar_title: #3C76C2, theme: default}
Expression Variable Reference
There are a number of predefined variables in the expression language. The following list all of the available variables:
Table 1.
Variable | Description | Usage |
---|---|---|
NOW | Current day and time | [multiblock cell omitted] |
TODAY | Current day at midnight (12:00 am) | [multiblock cell omitted] |
THIS_MINUTE | [multiblock cell omitted] | [multiblock cell omitted] |
NEXT_MINUTE | Now + 1 minute | [multiblock cell omitted] |
PREV_MINUTE | Now + 1 minute | [multiblock cell omitted] |
THIS_HOUR | This hour at 0 minutes | [multiblock cell omitted] |
NEXT_HOUR | THIS_HOUR + 1 hour | [multiblock cell omitted] |
PREV_HOUR | THIS_HOUR - 1 hour | [multiblock cell omitted] |
NEXT_DAY | Today + 1 day | [multiblock cell omitted] |
THIS_YEAR | The first day of this year at midnight (12:00am) | [multiblock cell omitted] |
NEXT_YEAR | THIS_YEAR + 1 year | [multiblock cell omitted] |
PREV_YEAR | THIS_YEAR - year | [multiblock cell omitted] |
THIS_MONTH | the first day of this month at midnight (12:00am) | [multiblock cell omitted] |
NEXT_MONTH | THIS_MONTH + 1 month | [multiblock cell omitted] |
PREV_MONTH | THIS_MONTH - 1 month | [multiblock cell omitted] |
NEXT_***DAY | Replace * with a particular day of the week | NEXT_MONDAY: the next day that is a Monday at midnight |
PREV_***DAY | Replace * with a particular day of the week | PREV_SATURDAY: the last day that was a Saturday at midnight |
**_DAY_AGO | Replace ** with any number between 1 and 12 | 10_DAY_AGO: today - 10 days |
**_DAY_AHEAD | Replace ** with any number between 1 and 12 | 5_DAY_AHEAD: today + 5 days |
**_WEEK_AGO | Replace ** with any number between 1 and 12 | same usage as **_DAY_AGO |
**_WEEK_AHEAD | Replace ** with any number between 1 and 12 | same usage as **_DAY_AHEAD |
**_MONTH_AGO | Replace ** with any number between 1 and 12 | same usage as **_DAY_AGO |
**_MONTH_AHEAD | Replace ** with any number between 1 and 12 | same usage as **_DAY_AHEAD |
**_YEAR_AGO | Replace ** with any number between 1 and 12 | same usage as **_DAY_AGO |
**_YEAR_AHEAD | Replace ** with any number between 1 and 12 | same usage as **_DAY_AHEAD |
These variables can be used for to refer to state information in searches. This expression will retrieve all the login information for the current user.
@GET(sthpw/login['login',$LOGIN])
They can also be used to find items between certain dates. This expression will retrieve all snapshots for this week starting at Sunday.
@GET(sthpw/snapshot['timestamp','>',$LAST_SUNDAY]['timestamp','<',$NEXT_SUNDAY])
The following are shorthands that do not require a starting point or environment sobject. They can be used in an absolute expression:
The following are shorthands that require a starting point or environment sobject:
connect - the connected sobject registered in the connection sType. Refer to the API methods like connect_sobjects() and get_connected_sobjects()
To filter down to a particular connected sobject based on the context attribute, which defaults to task, use @CONTEXT.
e.g. @GET(prod/asset.connect[@CONTEXT,some_task].description)
The following variables are only used in Naming. Refer to the file naming section for details.
Exception Log
The exception log SObjects provides a very convenient way for TACTIC to store, view and diagnose problems or errors in TACTIC as they come up. This is a necessary requirement in order to properly diagnose a bug or error that will arise.
A default view of the exception log is available in the "Admin" section of the Schema Sidebar
Because TACTIC records every stack trace in the system, it is possible to simply find the last stack trace generated by a particular user. This eliminates the need to constantly reply to an error report asking for the stack trace of the error (which by then is often lost because the user has decided to work on another task). With the exception log, it becomes trivial to look up the error witnessed by the user and start diagnosing the problem.
What is a Widget
A TACTIC Widget is a mini web program which serves a specific purpose and can be reused. This is what the TACTIC interface is composed of. Each interface view is presented to a user or a group of users in a combination of widgets which can accomplish many things:
Each of the widgets is a "snippet" of web code (HTML) which TACTIC builds dynamically on the server and delivers to the user as a web page; but the TACTIC interface is much more than a web page. TACTIC takes full advantage of the newest web technology to deliver a flexible and robust web application.
This widget architecture allows TACTIC to provide a toolbox of useful widgets which can be combined to build an interface which can adapt TACTIC to an work flow. Furthermore, due to the openness of TACTIC, it is easy for developers to create new widgets and share them.
Widget Documentation
Within this documentation, the same philosophy will be followed. There is a section which explains the usage of each widget but the main core of the documentation explains how to use them in combination or with existing interfaces to work with TACTIC.
A few examples of the common TACTIC widgets are:
Description
This widget displays the value in the database "as is", in its raw unformatted form. This is the default display widget.
Note
The Simple Table Element widget is the same as the Raw Data widget.
Info
Name | Simple Table Element |
Class | raw_data |
TACTIC Version Support | 3.0.0 \+ |
Required database columns | none |
Implementation
Use this widget to display the value in the database "as is", without any pre-formatting. This widget is the default display widget.
Options
type | The database type: string, text, int, float, boolean, timestamp |
Example
For example, to display the keywords field, as is, from the Edit Column Definition→View Mode: Select Widget → Raw Data → text.
Advanced
Below is the XML for the above example.
<element name="keywords" title="test" edit="true" color="false"> <display widget="raw_data"> <type>text</type> </display> </element>
The Formatted Widget displays a raw data value as a formatted string so the user can recognize and interpret the value more easily.
For example, the Format Widget will display a number in the format $1,234.00 which the user quickly recognizes as a currency value in dollars and cents.
Name | Formatted Widget |
Class | FormatElementWdg |
Category | Simple Table Element Widget |
Supported Interfaces | [] |
TACTIC Version Support | 3.6.0+ |
Required database columns | none |
integer | |
float | |
percent | |
currency | |
date | |
time | |
scientific | |
boolean | |
timecode |
Expression
Description
The ExpressionElementWdg allows you to use the TACTIC expression language to determine the value displayed in the table cell. The expression is caclulated from a starting sobject which represents the sobject in the particular row in the table. The expression is evaluated for each sobject on every row. When an expression is evaluated, the value is added to a dynamic attribute of the sobject and can be used in future expressions in this widget. Please refer to the expression language reference for more information on the expression language.
Info
Name | ExpressionElementWdg |
Class | tactic.ui.table.ExpressionElementWdg |
Category | Common Columns |
Supported Interfaces | TableLayoutWdg |
TACTIC Version Support | 2.5.0 |
Required database columns | depends on expression |
Implementation
Display the total cost of an item by multiplying the total_number column with the unit_cost column When an expression is evaluated by the ExpressionElementWdg, a new attribute with the name of the element is dynamically added to the sobject (in this cost) which can be used in the "bottom" directive.
<element name='cost'> <display class='tactic.ui.table.ExpressionElementWdg'> <expression>@GET(.total_number) * @GET(.unit_cost)</expression> <bottom>@SUM(.cost)</bottom> </display> </element>
Options
expression | Expression to evaluate the widget |
display_format | Display format string like DATETIME, DATE, -$1,234 applicable for various Formatted Element can be used here. |
inline_styles | Styles to add to the DIV generated that contains the result of the expression |
return | single |
list - Determines what the expression return type should be | bottom |
Expression to calculate the bottom row of the table | group_bottom |
Expression to calculate the group bottom row of the table | mode |
value | boolean |
check | icon - Display mode for this widget |
expression_mode | default |
absolute - If absolute mode is selected, it does not relate to the current SObject | calc_mode |
fast | slow - fast uses new calculation mode. Only @SUM, @COUNT, @SOBJECT and @GET are current supported |
enable_eval_listener | Currently javascript expression evaluation is not fully baked, so only use the client side evaluation listener when needed and NOT by default |
icon_expr | Expression to evaluate which icon to use when mode = icon |
order_by | provide a simple string to order by e.g. code or by an attribute in a related sType in the same database, e.g. prod/sequence.dsecription |
group_by | true |
false - Turn on group by in context menu if set to true | group_by_time |
true | false - Turn on group by time options in context menu if set to true |
justify | default |
left | right |
Examples
Display the number of tasks for a given sobject and then display the total number at the bottom.
<element name='num_tasks'> <display class='tactic.ui.table.ExpressionElementWdg'> <expression>@COUNT(sthpw/task)</expression> <bottom>@SUM(.num_tasks)</bottom> </display> </element>
Mode "boolean" displays a green dot for every sobject that has an expression that evalutes to True. In this case, a green dot is display on every row where the number of tasks is greater than zero.
<element name='has_tasks'> <display class='tactic.ui.table.ExpressionElementWdg'> <expression>@COUNT(sthpw/task) > 0</expression> <mode>boolean</mode> </display> </element>
Another example of a mode which displays a checkbox instead of red/green dots. The checkbox appears for any result greater than zero
<element name='has_tasks'> <display class='tactic.ui.table.ExpressionElementWdg'> <expression>@COUNT(sthpw/task) > 0</expression> <mode>check</mode> </display> </element>
The expression language has the ability to get values from other related tables. The following example illustrates an expression to find the description of the parent sequence of a shot.
<element name='sequence_description'> <display class='tactic.ui.table.ExpressionElementWdg'> <expression>@GET(prod/sequence.description)</expression> </display> </element>
The expression language has the ability to get values from other related tables and format it using the DATETIME project setting which can be customized per project
<element name='task_due_date'> <display class='tactic.ui.table.ExpressionElementWdg'> <expression>@GET(sthpw/task.bid_end_date)</expression> <display_format>DATETIME</display_format> </display> </element>
Ultimately, the ExpressionElementWdg can make use of any expression in the TACTIC Expression Lanaguage.
When using mode = icon, it is possible to set up an expression using icon_expr to determine what that icon should be. A special variable $VALUE is used to determine the value of the expressions
<element name="is_synced" title='Synced' edit='false'> <display class='tactic.ui.table.ExpressionElementWdg'> <expression>@GET(.is_synced) == True</expression> <mode>icon</mode> <icon_expr>@IF( '$VALUE' == True, 'CHECK', 'CROSS' )</icon_expr> </display> </element>
Description
The Select Widget is a simple widget version of an HTML drop down selection box. The widget is used for making a selection from a predefined list of items. Many built-in dropdown widgets in TACTIC extend from the Select Widget.
Info
Name | Select Widget |
Class | SelectWdg |
TACTIC Version Support | 2.5.0 \+ |
Required database columns | None, but typically this is attached to a data column |
Usage
Usage of the Select Widget is straightforward. Simply click on the Select Widget button to open the drop down selection box. Then, select one of the menu items. Sometimes items are grouped and separated by a group label represented as << label>>. In that case, selecting the group label will trigger a warning pop-up. To unset a value, you can usually select the empty value with the label -- Select --.
Implementation
The select is often setup in the Edit Column definition → Edit Tab. It is edited for the state for column data where the user should only be able to choose from a list of predefined values.
Options
values | A list of data values separated by the pipe character |, e.g. model|anim|lighting |
labels | A list of display labels separated by the pipe character |, e.g. Model|Anim|LGT |
empty | When set to true, the Select Widget will contain an empty option. |
values_expr | This serves the same purpose as values but in the form of an expression. The input item of the expression has to exist for this to function properly.(ie @GET(vfx/sequence.code) ). If it is used in the menu of an item in insert mode, you should set mode_expr to absolute |
labels_expr | This serves the same purpose as labels but in the form of an expression. The input item of the expression has to exist for this to function properly (ie @GET(vfx/sequence.name) ). If it is used in the menu of an item in insert mode, you should set mode_expr to absolute |
mode_expr | If left unset, the default is to use the current item in the expression defined in values_expr and labels_expr. If set to absolute, the input item for the expression will be an empty list. |
query | In the form of <search_type>|<value>|<label>, you can instruct the widget to retrieve the values and labels from the a particular sType. For example, to get all the asset codes from the sType vfx/asset, you can use vfx/asset|code|code. To change the label to display asset’s name instead, you can use vfx/asset|code|name. |
Advanced
The following example uses the query option to get the code of a parent shot item but, display the name value in the list. This query option is older. The values_expr and labels_expr option are preferred.
<element name="parent_code"> <display class="SelectWdg"> <query>prod/shot|code|name</query> </display> </element>
The following gets the same result but, uses expressions. This allows for more robust queries for values and labels.
<element name="parent_code"> <display class="SelectWdg"> <mode_expr>absolute</mode_expr> <values_expr>@GET(prod/shot.code)</values_expr> <labels_expr>@GET(prod/shot.name)</labels_expr> </display> </element>
The following sets a hard coded list of values and labels for the SelectWdg.
<element name="status"> <display class="SelectWdg"> <values>waiting|in_progress|complete</values> <labels>Waiting|In Progress|Complete</labels> </display> </element>
Description
The TextAreaWdg is a simple text widget which is used for editing full-text. The widget supports using the ENTER key for adding new lines (the ENTER key is often not supported on text entry widgets where CTRL+ENTER is used.) This widget can also be configured to display a larger canvas to work on.
Info
Name | TextAreaWdg |
Class | pyasm.widget.TextAreaWdg |
TACTIC Version Support | 2.5.0 |
Required database columns | requires a database column for storing the text data. |
Implementation
The TextAreaWdg is used in Edit scenarios where full text input is required. There is control for the columns (characters across) and rows (characters down).
Options
cols | The number of character columns in the TextArea |
rows | The number of character rows in the TextArea |
Advanced
The following example is a default implementation. The default number of cols is 50 and the default number of rows is 3.
<element name="subject"> <display class="TextAreaWdg"/> </element>
The following example creates a large text area which could be used for writing large amounts of full-text.
<element name="summary"> <display class="TextAreaWdg"> <cols>100</cols> <rows>30</rows> </display> </element>
Calendar Input Widget
Description
The CalendarInputWdg displays a navigable calendar where dates can be selected. It is an input widget that conforms to the BaseInputWdg interface and is used for inline editing or as one of the items in the EditWdg layout.
Info
Name | Calendar Input |
Class | tactic.ui.widget.CalendarInputWdg |
Category | Input widget |
Supported Interfaces | EditWdg, TableLayoutWdg (edit view) |
TACTIC Version Support | 2.5.0 |
Required database columns | none unless editing a specific date column |
Implementation
The simple implementation does not require any options. It displays a non-editable text box with a value that represents a date. Clicking on the cell opens up the calendar widget.
Options
first_day_of_week | Integer representing first day of the week (0=Sunday, 6=Saturday) |
read_only | Sets the widget to be read only. In read-only mode, clicking on the cell does not bring up the calendar for input. Only a text box with the date value is displayed. |
Advanced
The simplest and most common usage is the default implementation.
<element name='start_date'> <display class='tactic.ui.widget.CalendarInputWdg'/> </element>
To set the work week to start on a different day than Sunday, change the first_day_of_week . This option is an integer which represents the days of the week where 0=Sunday and 6=Saturday.
<element name='start_date'> <display class='tactic.ui.widget.CalendarInputWdg'> <first_day_of_week>6</first_day_of_week> </display> </element>
Description
The Task Completion Widget provides a graphical bar chart to represent the progress of an item by the completion rate of its child tasks.
Info
Name | Task Completion Widget |
Common Title | Task Completion Widget |
Class | tactic.ui.table.TaskCompletionWdg |
TACTIC Version Support | 2.5.0 |
Required database columns | none |
Usage
This is a display-only widget. If all the tasks are completed for a shot, the bar reading would be 100%. Otherwise, a partial completion would be calculated based on tallying all the child tasks. If there are no tasks for the item, "No tasks" is displayed.
Implementation
It is a common column that can be added using the Column Manager. The item name is "completion".
Options
task_expr | An expression to get to the tasks relative to the current sObject. e.g. @SOBJECT(prod/shot.sthpw/task) |
Advanced
<element name="completion" edit="false"> <display class="tactic.ui.table.TaskCompletionWdg"/> </element>
How The "Completion" is Calculated
Example 1:
Let’s say that we have a task in a pipeline with the following processes:
4 processes: Design, Rough, Modeling, Delivery
Let’s say that for each process, there are:
4 statuses: Unassigned, In Progress, Ready_for_Review, Approved.
If the task is in the status: Unassigned, the task is 0% complete.
If the task is in the status: Started, the task is 33.3% complete.
If the task is in the status: Ready_for_Review , the task is 66.6% complete.
If the task is in the status: Approved, the task is 100% complete.
Let’s say the task in the Rough process has the status Approved. That means that is 100% complete for the Rough process. In the other 3 processes, it is at Unassigned, which is 0% complete.
Then, the TOTAL completion would be (1.0 + 0 + 0 + 0 ) / 4 = 25% complete.
Example 2:
Using the same process and task statuses, let’s say the task in the Rough process has the status Ready_for_Review. That means that is 66% complete for the Rough process. In the other 2 processes, it is at Started, which is 33.3% complete. In the last processes, it is at Unassigned, which is 0% complete.
Then, the TOTAL completion would be (0.666 + .333 + .333 + 0 ) / 4 = 33.3% complete. .
Explorer Button
Description
The Explorer Widget can be configured to launch Windows Explorer for Windows (or Finder for OSX). It can be configured to open to a directory which is either the sandbox or to the repository of the corresponding item.
Info
Name | Explorer |
Class | tactic.ui.table.ExplorerElementWdg |
Category | Common Columns |
TACTIC Version Support | 3.0+ |
Required database columns | none |
Implementation
When added to the view, the Explorer Widget button is represented as an icon of a folder. The button opens up Windows Explorer (or Finder on OSX). This gives the user a quick starting point for navigating to a directory that is relevant to the corresponding item. The convenience is greater when the repository contains a lot of items or the directory folder structure is very deep. Users save time by not having to navigate through endless directories to get to where they need to go to do work.
By default, the Explore Widget opens a window to the corresponding item if it exists in the user’s sandbox.
Options
mode | sandbox |
Advanced
The following example configures the Explorer Widget to browse to the assets directory as specified in the Tactic Config File
<element name='explorer'> <display class='tactic.ui.table.ExplorerElementWdg'> <mode>client_repo</mode> </display> </element>
<element name='explorer'> <display class='tactic.ui.table.ExplorerElementWdg'/> </element>
General Check-in Widget
Description
This is the new preferred Check-in Widget for 3.7+. It makes use of the Java Applet to accomplish various kinds of check-in functions like checking in a single file, sequences of files, or directories. The copy or preallocate transfer mode should be used when dealing with a large file transfer. Upload transfer mode only supports checking in single files and sequences of files. Upload is set to be the default in case new users do not have the handoff directory readily set up.
Info
Name | General Check-in Widget |
Class | tactic.ui.widget.CheckinWdg |
Category | Widget |
Supported Interfaces | TableLayoutWdg |
TACTIC Version Support | 3.7.0 |
Required database columns | none |
Options
transfer_mode | upload, copy and move are supported. copy is recommended for most situations when users are usually granted only read access to the TACTIC asset repo. (default is copy) |
mode | sequence, file, dir, and add are supported. sequence is for file sequence checkin; file is for single file checkin; dir is for directory checkin; and add is for appending file or dir to an existing snapshot. If not specified, multiple selections will be available for the user to choose. Note: upload transfer mode only supports single file or file sequence checkin. |
checkin_script_path | a custom checkin script path to specify an override on what functions get called during a checkin. Note: If trying to do some preprocessing with the file or directory before checking in, just make use of validate_script_path function using Client Trigger. Client Trigger works by setting up this check-in script as a Client Trigger callback that affects the search type rather than just a column definition. |
validate_script_path | a script path pointing to a JavaScript file that is run before the actual checkin. If it throws an error using "throw(<error message>)", the checkin will not initiate. This path can also use it to run some client-side preprocessing of the file or directory. It is not set up as a display option but rather as a Client Trigger callback. |
checkout_script_path | a custom check-out script path to specify to override what happens during a check-out. |
process | If set, the process specified will be pre-selected when the General Check-in Widget is drawn, |
lock_process | If set to true, the user will not be able to choose a different process during a checkin, in the General Check-in Widget |
show_context | When set to true, the context will be displayed to the user. (default is false) |
Gear Menu Options
The Gear Menu in the Check-in Widget provides the following administration options:
Edit Process | Load the process options pop-up. The process and subcontext options are described further in the sections below |
List Processes | List all of the processes for the current pipeline. This provides the same access to the as the Edit Process option but for all processes. |
Show Server Transaction Log | Show the standard server transaction log |
Undo Last Server Transaction | Undo the last transaction. When undoing a checkin, the files will also be removed in the file system. |
Redo Last Server Transaction | Redo the last transaction. When redoing a checkin, the files will be restored in the file system. |
Implementation
The default settings will allow a user to check in files to an assets in the "publish" process. It provides a very general and loosely enforced workflow to check in and manage files. Often, it is required, that a particular process has very strict enforcement of naming conventions and check-in procedures.
The General Check-in widget is highly configured and can be tuned precisely for each part of the process. The various customizations can fall into the following categories:
Validation, Subcontext options, Custom interface, Custom check-in script, Naming conventions
Each of these can be customized for the particular widget or at the process level.
Validation
Validation is a custom script that will is run before the check-in process occurs. It provides the ability to check that all files in the checkin conform to some custom logic required for a successful checkin. If the validation script fails, then the entire checkin is aborted.
Client Side Triggers
A client trigger set up allows control over what check-in script or validate_checkin script to call during a checkin. Here is an example of how to set the checkin/validate_folder script to run before the check in of prod/asset. The event name is CheckinWdg|validate_script_path|<search_type>. If only a particular process is desired to be run on check in for, like "texture", the event name would become CheckinWdg|validate_script_path|prod/asset|texture. To override the checkin_script_path, use the event CheckinWdg|checkin_script_path|<search_type>. If this event-based set-up seems a bit too involving, override the checkin_script_path for just this instance of the widget by using the standard display option <checkin_script_path>.
Process Options
By default, the subcontext selection is set to (auto). It is the simplest to use and allows TACTIC to auto generate the subcontext. Because the subcontext is auto generated, strict naming conventions for the file are often sacrificed for ease of use. By default, the checked in file will just have a version number attached to it.
It is possible to force a limited list of subcontext options on a particular checkin. This means that the files checked in will be named according to the subcontext selected and provides a limited set of approved containers in which files can be checked in.
Process/Context/Subcontext
Checkin’s are always categorized by process. If there is no pipeline defined, the default process "publish" will be used. Categorizing checkin’s by the process in the pipeline of an asset organizes the work done for an asset according to its product life cycle.
Another important attribute of a checkin is the context. Assets are versioned according to their context which provide a namespace for versioning checkin’s of an asset. All checkin’s of an asset with the same context are versioned together. The context of an asset is a particular way to view an asset.
For example, a 2D drawing of a character and a 3D model of the same character represent the same abstract asset, so are two different contents of the asset. This can be implemented in TACTIC by specifying the following in the Check-in Widget’s Context Options:
Context Options: 2D_drawing|3D_model
Although the context can be any string, most often, it is built up from other parameters. The convention usually used is "<process>/<subcontext>". All of TACTIC’s built-in check-in tools assume this relationship. The subcontext provides a namespace for checking in multiple subcategories of files within a single context.
The following is an example of these subcontext options:
Subcontext Options: hi|med|low
Naming conventions are often strictly enforced, meaning that the folder and the file name are automatically supplied on check in of a file to the central repository.
Default Check-in Widget Options
In the panel on the right, when something from the list is selected for check in, the corresponding Check-in type (e.g.. file, directory, sequence, multiple individual files) is automatically selected by the Check-in Widget.
For example, on the panel on the right, if a file is selected for check in, the Check-in type will automatically switch to A File under the Check-in Options on the bottom left:
For example, if a folder is selected to check in on the right panel, the Check-in type will automatically switch to A Directory under the Check-in Options on the bottom left:
More Context and Subcontext Examples
Example 1)
To check in high resolution and low resolution files for a model process, first specify the context_options under:
Checkin Widget → Gear Menu → Edit Process:
Specify the following Context Options:
Context Options: model/hi|model/lo
OR specify the following Subcontext Options:
Subcontext Options: hi|lo
Both of the choices above give the same result.
Result:
process = model context = model/hi (or model/lo)
Only use either the context field or the subcontext field but not both fields.
Note
If values are specified for both the context_options and the subcontext_options, only the context_options will be used (the subcontext_options will be ignored).
Example 2)
To provide the same options (hi and lo) and avoid using subcontexts specify the following context_options:
context_options: model_hi|model_lo
Result:
process = model context = model_hi (or model_lo)
Notice that the forward slash / was not used, which avoids using subcontexts.
Example 3)
The following is another example of how to avoiding using subcontexts altogether.
To check in a proxy and a staging context for a model process, specify the following context_options:
context_options: model_proxy|model_staging
Result:
process = model context = model_proxy (or model_staging)
Again, notice that the forward slash / was not used, which avoids using subcontexts.
Subcontext Keywords: (auto), (main) and (text)
The following subcontext option keywords are supported:
(auto) | Uses the filename as the subcontext (auto is the default if no values are specified for the context or subcontext options) |
(main) | Uses the process as the context |
(text) | Allows the user to specify their own context for the file to check in |
Example for (auto):
process: | design |
filename: | my_checkin_file.txt |
subcontext option selected: | (auto) |
Result:
context = design/my_checkin_file.txt
Example for (main):
process: | design |
subcontext option selected: | (main) |
Result:
context = design (because is the process)
Example for*(text)*:
To check in different colors of a car for the design process eg. a green version of the car and a red version
process: | design |
subcontext option selected: | (text) |
custom context inputted | green |
Result:
context = design/blue
Providing a Custom Layout View For the Check-in Options
A custom layout view can be provided in the check-in panel as options.
For example, to provide check boxes during the check in to submit the job to the render farm or to submit the file for the review process, create a custom view and specify the view in the Check Options View.
To do this, first, create a custom view under:
Admin Views → Project → Widget Config
Below is an example of a custom layout view:
note:
In the example custom view above, to make use of these custom UI check boxes, more work needs to be done to override the checkin_script or checkin_validate_script.
The checkin_script and the checkin_validate script can be found under: Checkin Widget → Gear Menu → List Processes
Example validate scripts can be found at the end of this Check-in Widget doc in the section labeled Example Scripts: Example 1 and 2.
Then, specify the name of the view under:
Checkin Widget → Gear Menu → List Processes
In the Check-in Options View, specify the name of the custom layout view for the check-in options:
Finally, select a file to check in, the custom view with the check-in options will appear on the panel on the left.
Without custom check-in options: | With customer check-in options: |
Script Samples
This script can be saved in the Script Editor accessible through the Gear Menu.
Example 1: checkin/validate_folder
var values = bvr.values; var file_path = values.file_paths[0]; var sk = values.search_key; var applet = spt.Applet.get(); var file_list = applet.list_dir(file_path); for (var i=0; i <file_list.length; i++){ var base =spt.path.get_basename(file_list[i]); if ( base == 'DATA') { throw('it contains a DATA folder. Checkin aborted'); } }
Example 2: checkin/validate_file
var values = bvr.values; var file_path = values.file_paths[0]; var sk = values.search_key; var applet = spt.Applet.get(); var base =spt.path.get_basename(file_path); if ( base.test(/\\.mov$/)) { throw('it does not have a mov extension. Validation failed.'); }
Example 3: Custom checkin_script using display option "checkin_script_path". Also retrieving and showing the values of checkboxes. The default snapshot_type is file, if the file extension is .mov, the snapshot_type is set to mov.
var file_paths = bvr.values.file_paths; var description = bvr.values.description; var search_key = bvr.values.search_key; var context = bvr.values.context; var transfer_mode = bvr.values.transfer_mode var is_current = bvr.values.is_current; var path = file_paths[0] spt.app_busy.show("File Checkin", path); var values_dic = bvr.custom_options; console.log(value_dic); var snapshot_type = 'file'; if (path.test(/\\.mov$/)){ snapshot_type = 'mov'; } var server = TacticServerStub.get(); snapshot = server.simple_checkin(search_key, context, path, {description: description, mode: transfer_mode, is_current: is_current, snapshot_type:'mov'});
Advanced
The General Check-in Widget is usually invoked with a CheckinButtonElementWdg with a transfer mode specified. In this implementation, the process will be preselected as "texture", providing the pipeline for this sObject does contain a process named texture.
<element name='general_checkin' title=' '> <display class='tactic.ui.widget.CheckinButtonElementWdg'> <transfer_mode>copy</transfer_mode> <process>texture</process> </display> </element>
In this implementation, the process will be preselected as "model", providing the pipeline for this sObject does contain a process named model. The user cannot switch to other processes in the pipeline, and only "New Directory" mode can be selected.
<element name='general_checkin' title=' '> <display class='tactic.ui.widget.CheckinButtonElementWdg'> <transfer_mode>copy</transfer_mode> <process>model</process> <lock_process>true</lock_process> <mode>dir</mode> </display> </element>
Description
The Checkin History Widget is a toggle that opens a hidden row that displays all the snapshots (snapshots are checkins at a particular moment in time for a context) for an item.
Info
Name | Checkin History Widget |
Common Title | History |
Class | tactic.ui.widget.SObjectCheckinHistoryWdg |
Category | Common |
TACTIC Version Support | 3.0.0 \+ |
Required database columns | none |
Usage
The following details are displayed by the Checkin History Widget for a task:
Implementation
The Checkin History Widget can be found as a common column that can be added using the Column Manager.
Options
There are no options provided for the Checkin History Widget.
Advanced
<element name="history" edit="false"> <display class="HiddenRowToggleWdg"> <icon>HISTORY</icon> <dynamic_class>tactic.ui.widget.SObjectCheckinHistoryWdg</dynamic_class> </display> </element>
Description
The Note Sheet Widget allows entering of many notes in different contexts and different parents at the same time. It can be used for entering notes for any search types. By default, it uses the parent’s pipeline processes as the contexts for note entry. Notes can be saved either individually or altogether. There is an option to make a note private as well.
Info
Name | Note Sheet Widget |
Common Title | Note Sheet |
Class | tactic.ui.app.NoteSheetWdg |
Category | Table Element Widget |
Supported Interfaces | TableLayoutWdg |
TACTIC Version Support | 2.5.0 |
Required database columns | none |
Usage
When used with regular sTypes with its pipeline_code set, the Note Sheet Widget automatically displays the pipeline processes as note context options. Each enabled context is marked with a check in the check box, which goes along with a text box for note entry. Indicate which contexts display for input by selecting the appropriate check boxes. When used with a child search_type like a task, the Note Sheet Widget assumes its context attribute as the note context.
Clicking on "save" icon will save all of the notes together for this parent. To save one note at a time, click on the individual save button under the corresponding note.
The private check box turns a note access as private if checked. The history button is used to display all the note entries for a context.
Implementation
The Note Sheet Widget is a common column that can be added using the Column Manager.
Options
dynamic_class | Set the class name of the widget to be displayed |
pipeline_code | Specifies a particular pipeline_code to use or if the parent of this note sheet widget does not have the pipeline_code attribute e.g. model. If unspecified, it will be based on the pipeline_code value of its parent. |
element_class | To override the default element class NoteTableElementWdg, modify the look or add extra buttons to the UI to enter notes. One method is just to override the method get_action_wdg() |
use_parent | When a note sheet is added to a sType like task or snapshot but it is set up so that the note is targeted at its parent, which could be an asset or shot. If so, set this display option to true. |
append_context | Used to add contexts that are not defined in the pipeline. Separate the contexts with a pipe character if there are more than one, e.g. producer |
Advanced
<element name="notes_sheet" edit="false"> <display class="HiddenRowToggleWdg"> <dynamic_class>tactic.ui.app.NoteSheetWdg</dynamic_class> </display> </element>
Description
The Task Edit Widget is a toggle that opens a hidden row that displays all the tasks for an item. If there are multiple processes for an item, the tasks for those processes will be displayed.
Info
Name | Task Edit |
Common Title | Tasks |
Class | tactic.ui.panel.TableLayoutWdg |
Category | Table Layout Widget |
Supported Interfaces | TableLayoutWdg |
TACTIC Version Support | 3.0.0 |
Required database columns | none |
Usage
The following details are displayed by the Task Edit Widget for a task:
Implementation
The Task Edit Widget is a common column that can be added using the Column Manager.
Options
There are no options provided for the Task Edit Widget.
Advanced
<element name="task_edit" title="Tasks" edit="false"> <display class="HiddenRowToggleWdg"> <dynamic_class>tactic.ui.panel.TableLayoutWdg</dynamic_class> </display> </element>
Description
The Task Schedule displays a horizontal bar graph representing the schedule of start/end date and duration for all tasks assigned to an item. This widget is a simple pre-configuration of the Gantt Chart widget.
Info
Name | Task Schedule |
Class | tactic.ui.table.GanttElementWdg |
Category | Common Columns |
TACTIC Version Support | 3.0+ |
Required database columns | none |
Implementation
The Task Schedule Widget is a common column that can be added using the Column Manager.
Options
The following is the configuration option which the makes this widget distinct from its derivative, the Gantt Chart widget.
[ { "start_date_expr": "@MIN(sthpw/task.bid_start_date)", "end_date_expr": "@MAX(sthpw/task.bid_end_date)", "color": "#33F", "edit": "true", "default": "false" }, { "start_date_expr": "@MIN(sthpw/task['context','model'].bid_start_date)", "end_date_expr": "@MAX(sthpw/task['context','model'].bid_end_date)", "color": "#F0C956", "edit": "true", "default": "false" } ]
Show Title | True or False Display the title in the column header. |
Date Mode | visible, hover Always display the start/end date next to the horizontal bar or display the dates only on cursor hover. |
Range Start Date | Select the start date range for the tasks to display. |
Range End Date | Select the end date range for the tasks to display. |
Show Milestones | task, project Display a red vertical bar representing the milestone for the task or the project |
Year Display | none, default Display the year in the column header. |
Week Display | none, default Display the week in the column header. |
Advanced
<element name="task_schedule"> <display class="tactic.ui.table.GanttElementWdg"> <options>[ { "start_date_expr": "@MIN(sthpw/task.bid_start_date)", "end_date_expr": "@MAX(sthpw/task.bid_end_date)", "color": "#33F", "edit": "true", "default": "false" }, { "start_date_expr": "@MIN(sthpw/task['context','model'].bid_start_date)", "end_date_expr": "@MAX(sthpw/task['context','model'].bid_end_date)", "color": "#F0C956", "edit": "true", "default": "false" } ]</options> </display> <action class="tactic.ui.table.GanttCbk"> <sObjects>@SOBJECT(sthpw/task)</sObjects> <options>[ { "prefix": "bid", "sObjects": "@SOBJECT(sthpw/task)", "mode": "cascade" }, { "prefix": "bid", "sObjects": "@SOBJECT(sthpw/task['context','model'])", "mode": "cascade" } ]</options> </action> </element>
Description
The Task Status History is a toggle that opens a hidden row that displays all the status changes for an item. If there are multiple processes for an item, the status updates for those processes will be displayed.
Info
Name | Task Status History |
Class | tactic.ui.panel.TableLayoutWdg |
Category | Common Columns |
TACTIC Version Support | 3.0+ |
Required database columns | none |
Implementation
The Task Edit Widget is a common column that can be added using the Column Manager.
Options
There are no options provided for the Task Edit Widget.
Advanced
<element name="task_status_history"> <display class="HiddenRowToggleWdg"> <dynamic_class>tactic.ui.panel.TableLayoutWdg</dynamic_class> <search_type>sthpw/status_log</search_type> <view>table</view> <expression>@SOBJECT(sthpw/task.sthpw/status_log)</expression> <mode>simple</mode> </display> </element>
Description
The Work Hours widget provides an interface to record the number of work hours spent for each task. The break down of the work hours by task allows the analysis to be broken down at the lowest level of detail.
Info
Name | Work Hours List |
Class | tactic.ui.table.WorkHoursElementWdg |
TACTIC Version Support | 2.5.0 |
Required database columns | none |
Implementation
The Work Hours List Element is a common column that can be added to any task view using the Column Manager.
Options
There are no options available for this widget.
view | The view to retrieve from the Widget Config. This is not required if the HTML option is supplied. |
html | This option is where the HTML code is embedded. |
search_type | The Search Type the CustomLayoutWdg applies to (if applicable) |
Examples
We can record 4 hours of work on Wednesday and 3 hours on Thursday for a task. The total for that week will also be displayed as a convenience.
Description
The Simple Upload Widget is used for uploading files in-line in tables and also in edit windows. It is the simplest form of Tactic checkin as is allows for uploading of a single file and uses only a single hard coded (configured) checkin context.
Info
Name | Simple Upload Widget |
Class | tactic.ui.widget.SimpleUploadWdg |
Category | Edit Widgets |
Supported Interfaces | TableWdg, EditWdg |
TACTIC Version Support | 2.5.0 \+ |
Required database columns | none |
Implementation
This widget is available as part of the "preview" common column. It is also used when right-clicking on an item and choosing "Change preview" or "Checkin File"
Options
Common Name(s)/Title | Preview, Snapshot, Files |
Context | TableWdg, EditWdg |
Show Preview? | 2.5.0 \+ |
Advanced
<element name='preview'> <display class='tactic.ui.widget.SimpleUploadWdg'> <context>icon</context> </display> </element>
Description
The View Panel is a composite widget which binds together a Table Layout Widget and a Search Widget. The Search Widget is a searching mechanism that retrieves items and transfers them to a Table Layout Widget to draw. The View Panel Widget is used in most of TACTIC’s predefined views.
Info
Name | View Panel |
Class | ViewPanelWdg |
TACTIC Version Support | 2.5.0 |
Required database columns | none |
Implementation
The View Panel widget makes use of the TableLayoutWdg capabilities. The views available to the View Panel are identical to that of the Table Layout Widget.
Options
show_gear | Flag to show the gear menu. |
show_search | Flag to show the search box. |
show_search_limit | Flag to show the search limit. |
show_insert | Flag to show the insert button. |
insert_view | Specify the path to a custom insert view. |
edit_view | Specify the path to a custom edit view. |
show_commit_all | Flag to show the commit all button. |
show_refresh | Display the refresh button on the shelf. |
show_row_select | Flag to show row_selection. |
popup | Pop the view up in a pop-up window. |
layout | default, tile, static, raw, fast_table, old_table |
search_type | The type that this widget works with |
view | The TACTIC name for the view. e.g. admin.test_asset_tracking |
do_initial_search | Run the search on loading of the view. |
simple_search_view | Specify the simple search view. |
custom_filter_view | View for custom filters. Defaults to "custom_filter". |
process | The process which is applicable in the UI when load view is used. |
mode | simple, insert |
parent_key | Provides a parent item to filter in the search. |
search_key | Provides the starting search key. |
element_names | Provides a list of column names (ie. "preview,name,description") for the view. |
schema_default_view | (INTERNAL) flag to show whether this is generated straight from the schema. |
order_by | The column name to order ascending by. |
search_view | (INTERNAL) View for custom searches. |
width | Set the default width of the table |
expression | Use an expression for the search. The expression must return items. |
filter | JSON data structure representing the settings for SearchWdg |
Advanced
Often, the ViewPanelWdg is defined from a side bar link. It can be defined by XML as follows
<element name='summary'> <display class='tactic.ui.panel.ViewPanelWdg'> <search_type>sthpw/task</search_type> <view>task_summary</view> </display> </element>
Custom Layout
Description
The Custom Layout Widget is a simple tool which opens up an incredible amount of customizable interface flexibility and integration from within the TACTIC UI. This widget provides a container in the web page which supports embedding of HTML code including TACTIC Widgets, Expressions and Behaviours. This allows development of complex widgets similar to the standard widgets delivered with TACTIC.
With this, the following examples can be achieved:
Info
Name | CustomLayoutWdg |
Class | tactic.ui.panel.CustomLayoutWdg |
TACTIC Version Support | 2.5.0 |
Required database columns | none |
Implementation
The Custom Layout Widget in its simplest form is a delivery mechanism for HTML code. The following "Hello World" example below demonstrates this.
<element name="hello_world"> <display class="tactic.ui.panel.CustomLayoutWdg"> <html> <h2>Hello World</h2> </html> </display> </element>
Where a large part of the considerations for usage of a Custom Layout is where it will be embedded and how it will get retrieved. There are a few ways to implement this widget:
Once a delivery method has been decided, it also needs to be decided if the custom Layout will need to evaluate based on an item being passed in as the parent or starting point (technically speaking a relative expression). For example, to use a CustomLayout to display a report for a item, the dynamic data in the CustomLayout needs to be derived starting from the specified item.
Taking advantage of relative expressions is usually accessed/assumed through the search_key value for the widget. This is most often done through TACTIC Expressions embedded in the HTML code or, through JavaScript code interacting with the CustomLayout. Either way, the search_key value must me passed into the widget for relative behavior. A simple example is that a button in a table can pass in the search key based on the item (row) it was clicked for. This would allow for loading of a custom dashboard which shows all information pertaining to that item.
Embedded Expressions
Expressions can be embedded in the Custom Layout through usage of a [expr] style tag. This Tag allows for embedding of expressions that are evaluated before the HTML which provide the resulting values into the HTML code.
The following example displays the task status of the modelling process.
<element name="hello_world"> <display class="tactic.ui.panel.CustomLayoutWdg"> <html> <div> Model Status: [expr]@GET(sthpw/task['process', 'model'].status)[/expr] </div> </html> </display> </element>
Embedded Widgets
The CustomLayoutWdg provides full support for embedding of TACTIC Widgets. For example TableLayoutWdg and EditWdg can placed in a CustomLayout. This for allows, for example, the ability to create a dashboard which can show multiple Tables, CustomLayouts HTML, etc.
<element name="hello_widget"> <display class="tactic.ui.table.CustomLayoutwdg"> <html> <element name="tasks"> <display class="TableLayoutWdg"> <search_type>sthpw/task</search_type> <view>task_list</view> <mode>simple</mode> <do_search>true</do_search> </display> </element> </html> </display> </element>
Note
In the example above, the <search_key> option is automatically being passed the search_key from the state of the overall Custom Layout. What this will do is pass in the searhc key to the table which will automatically filter it to only show items related to the search_key (parent). For example in a dashboard for a shot, the tasks table will only display tasks related to the shot as opposed to all tasks in the system.
Embedded Behaviours
The Custom Layout also supports usage of the TACTIC JavaScript Behaviour system. With this, elements in the Custom Layout can contain embedded behaviours which allow for creation of custom interfaces and utilities. This opens up full a connection with the interface, clientAPI and Java Applet.
<?xml version='1.0' encoding='UTF-8'?> <config> <hello_world> <html> <span>This is a button:</span> <input type='button' class='spt_button1' value='Press Me'/> </html> <behavior class='spt_button1'>{ "type": "click_up", "cbjs_action": ''' alert('Hello World'); ''' }</behavior> </hello_world> </config>
Options
view | The view to retrieve from the Widget Config. This is not required if the HTML option is supplied. |
html | This option is where the HTML code is embedded. |
search_type | The Search Type the CustomLayoutWdg applies to (if applicable) |
Examples
Example 1a
This can be stored in the definition view and called as an element by name (<element name="hello_world"/>) or, directly in the view config.
If added to the definition, it will be available as a Widget Column in the Column Manager.
<config> <definition> <element name="preview"/> <element name="code"/> <element name="hello_world"> <display class="tactic.ui.panel.CustomLayoutWdg"> <html> <h2>Hello World</h2> </html> </display> </element> </definition> </config>
Example 1b
The following example shows how to create a sidebar link which loads a Custom Layout view defined in the Widget Config.
In the Widget Config enter the following hello_world view. This can be called from The Javascript code and sent to a popup.
2. The link can be configured in the Project Views Manager. Under the
action menu, select "New Link". In the pop-up, Fill the options as shown
in the following image.
3. Once the link is saved, select it in the Preview of Side Bar to load
its options into the Element Detail panel on the right. Once loaded
switch the mode to Advanced and double check that the XML config
contains the following:
<element name="hello_world" title="Hello World" icon="APPROVED" state="" is_visible="on"> <display class="LinkWdg"> <class_name>tactic.ui.panel.CustomLayoutWdg</class_name> <view>example01</view> </display> </element>
Example 1c
The following example shows how to create a CustomLayoutWdg View in the widget config then, call it from the Javascript Editor
In the Widget Config enter the following hello_world view. This can be called from The Javascript code and sent to a pop-up.
2. In the Javascript Editor create the following custom script example
to load the view into a pop-up.
kwargs = { view: 'hello_world', }; spt.panel.load_popup('Custom Layout Popup', \ 'tactic.ui.panel.CustomLayoutWdg', kwargs);
Description
The TableLayoutWdg is the primary widget used to layout tabular data. It is primarily driven by the widget configuration. The TableLayoutWdg has the ability to display complex widgets inside each cell, to inline edit the data and to color code cells. It is the widget that is most often used to display information within the TACTIC.
Info
Name | Table Layout |
Class | tactic.ui.panel.TableLayoutWdg |
TACTIC Version Support | 2.5.0 \+ |
Required database columns | none |
Implementation
The TableLayoutWdg makes use of "views" which are defined in the widget config for each project. When the Table is loaded as part of an interface, a view configuration is passed into it which defines which columns and widgets should be displayed in the view. Typically, these view configurations are automatically saved in the background when a user saves a view from within the TACTIC interface. The table itself provides the ability to add, remove, rearrange, resize and group columns which can then be saved out often as links in the sidebar.
The following shows a simplified version for an "asset tracking" view as saved in the background widget config.
<config> <asset_tracking layout="TableLayoutWdg" > <element name="preview" width="74px"/> <element name="asset_category_code" width="64px"/> <element name="code" width="61px"/> <element name="title" width="121.883px"/> <element name="description" width="276.75px"/> <element name="keywords" width="253.367px"/> <element name="general_checkin" width="27px"/> <element name="history" width="42px"/> <element name="task_edit" width="29px"/> <element name="task_status_edit" width="223.167px"/> </asset_tracking> </config>
The widget configuration is an XML document. In this example, it defines an "asset_tracking" view with elements (preview, asset_category, code, title, description, keywords, etc…).
To draw what to display, TableLayoutWdg looks at the list of elements defined in the widget config and draws a column for each element. TACTIC then draws a row for each item that was either retrieved from a search, an expression or by supplied items. Each cell in the table represents an item being drawn by the defined element for a given column.
While the top widget configuration defines the list of elements to draw the columns, the exact definition of each element do not necessarily appear here. There are a number of views which define an element. Some of these elements may be defined inline or they may be defined elsewhere. There is a set hierarchy which the TableLayoutWdg looks for to find the definition of a particular element.
The hierarchy which TableLayoutWdg looks to find the definition for an element is as follows:
The third and fourth locations only apply to predefined types that are shipped with TACTIC. All custom types will only use the first two.
Options
search_type | Defines the type that this table will be displaying. It is used both for finding the appropriate widget config and for handling search (if necessary). Defaults to "table". |
view | Defines the view that this table will displaying. It used to find the appropriate widget config to display the table. |
do_search | By default, the TableLayoutWdg will handle the search itself. However, certain widgets may wish to turn this functionality off because they are supplying the search (internally used by ViewPanelWdg) |
order_by | Add an explicit order by in the search |
expression | Use an expression to drive the search. The expression must return items. |
parent_key | Set a specific parent for the search |
width | Define an initial overall width for the table |
show_row_select | Flag to determine whether or not to show row_selection |
show_gear | Flag to determine whether or not to show the gear menu. |
show_insert | Flag to determine whether or not to show the insert button. |
insert_mode | aux |
inline | pop-up |
none - set the insert mode of the table | search_limit |
An overriding search limit. A value < 0 means no limit affecting the search | config_xml |
Explicitly define the widget config | element_names |
Advanced
Very often, the TableLayoutWdg is not used directly, but is used through the ViewPanelWdg, which combines the TableLayoutWdg with the SearchWdg. Using ViewPanelWdg will provide all the functionality in a table view
Using the TableLayoutWdg does provide a simpler view if the search is already known,
This simple example shows the login table and the objects are explicitly given.
from tactic.ui.panel import TableLayoutWdg div = DivWdg() table = TableLayoutWdg(search_type='sthpw/login', view='table') sObjects = Search("sthpw/login").get_sObject() table.set_sObjects(sObjects) div.add(table)
An expression can be set for the search as well.
from tactic.ui.panel import TableLayoutWdg div = DivWdg() expression = "@SOBJECT(sthpw/login)" table = TableLayoutWdg(search_type='sthpw/login', view='table',expression=expression) div.add(table)
This example embeds the login table with a "table" view in a CustomLayoutWdg.
<config> <login> <html> <h1>This is the login table</h1> <element name='login_table'/> </html> <element name='login_table'> <display class='tactic.ui.panel.TableLayoutWdg'> <search_type>sthpw/login</search_type> <view>table</view> <expression>@SOBJECT(sthpw/login)</expression> </display> </element> </login> </config>
The widget config views determine how the TableLayoutWdg draws itself. There are a few custom attributes that a view can define. The view can define many parts of how the TableLayoutWdg is displayed. The following hides the "insert" button and makes each of the cells non-editable. These attributes are useful for reports which are generally not editable.
<?xml version="1.0" encoding="UTF-8"?> <config> <simple insert='false' edit='false'> <element name="preview"/> <element name="code"/> <element name="name"/> <element name="description"/> </simple> </config>
Description
This widget provides a drop down selection menu of values for a column for the Simple Search to do filtering on.
Info
Name | Select Filter Element Widget |
Class | tactic.ui.filter.SelectFilterElementWdg |
TACTIC Version Support | 3.7+ |
Required database columns | none |
Options
title | The title for the Select Filter Element. For example: <element name=artist_name title=Artist Name> |
values (required) | The values to populate the drop down selection with. For example, it can be a TACTIC expression: <values_expr>@GET(sthpw/login.login)</values_expr> or, it can be a pipe separated list of values. For example: <values>new|open|in_dev|need_info|on_hold|need_validation|closed|invalid</values> |
column (required) | The table column to do the select from. For example: <column>asset_category_code</column> |
Implementation
Find or define the filter view in the Widget Config and use the following XML code as an example of what to add to the config:
<config> <custom_filter> <element name='dynamic'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@GET(project/asset_category.code))</values_expr> <column>asset_category_code</column> </display> </element> </custom_filter> </config>
For the above example, this filter will provide a list of asset category codes to select from.
Notice that an icon of a green light appears next to the filter if it is being used:
Example 1
The following example demonstrates the Select Filter Element Widget providing filtering options for scrum tickets.
Below is what the Select Filter Elements look like in the user interface:
Below is what the config for the above example looks like in the Widget Config:
<config> <custom_filter> <element name='assigned'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@GET(sthpw/login.login)</values_expr> <column>assigned</column> </display> </element> <element name='status'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values>new|open|in_dev|need_info|on_hold|need_validation|closed|invalid</values> <column>status</column> </display> </element> <element name='type'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@UNIQUE(@GET(scrum/ticket.type))</values_expr> <column>type</column> </display> </element> <element name='sprint'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@GET(scrum/sprint.title)</values_expr> <column>scrum/sprint.title</column> </display> </element> <element name='feature'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@GET(scrum/feature.title)</values_expr> <column>scrum/feature.title</column> </display> </element> <element name='product'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@GET(scrum/product.title)</values_expr> <column>scrum/feature.scrum/product.title</column> </display> </element> <element name='customer'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@UNIQUE(@GET(scrum/ticket.customer_code))</values_expr> <column>customer_code</column> </display> </element> </custom_filter> </config>
Example 2
The following example is from the VFX project. It demonstrates how the Select Filter Element Widget can provide filtering options on assets based on columns not belonging to the current table itself.
Below is the schema for the VFX project. From the asset search type, a Select Filter Element is built based for attributes in the asset_category, sequence, shot and search types.
Below is what the Select Filter Elements look like in the user interface:
Below is what the config for the above example looks like in the Widget Config:
<config> <custom_filter> <element name='keywords'/> <element name='asset_category'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@GET(vfx/asset_category.code))</values_expr> <column>asset_category</column> </display> </element> <element name='sequence'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@GET(vfx/sequence.code))</values_expr> <column>vfx/asset_in_sequence.sequence_code</column> </display> </element> <element name='shot'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@GET(vfx/shot.code))</values_expr> <column>vfx/asset_in_shot.shot_code</column> </display> </element> </custom_filter> </config>
Note: the column attribute can only point to sTypes of the local database. For example if you are in vfx project’s sequence page, you can’t filter for task status of a shot with <column>vfx/shot.sthpw/task.status</column>. An alternative is to use the Advanced Search Criteria’s children section or the cross_db attribute of the KeywordFilterElementWdg.
<!-- in a task view, search for the shot's title attribute--> <element name="keywords"> <display class="tactic.ui.filter.KeywordFilterElementWdg"> <mode>keyword</mode> <column>vfx/shot.title</column> <cross_db>true</cross_db> </display> </element>
Description
The Task Status Edit column is used to display the status of all tasks for the item. It also provides conveniences such as changing the status of the task and the assigned user.
Info
Name | Task Element Widget |
Common Title | Task Status Edit |
Class | tactic.ui.table.TaskElementWdg |
Category | Common Columns |
TACTIC Version Support | 3.0.0 |
Required database columns | none |
Usage
Once this column is added into the view, the drop down list can be used to change the status. In addition, this column also displays the process, schedule and the assigned user.
Implementation
This widget can be added using the Column Manager and can be found under the common columns as Task Status Edit.
Color
TACTIC provides the ability to assign each status its own color. Setting colors is handles from the Project Workflow (Pipeline) editor. Each process in a regular pipeline or a status pipeline can be assigned a color which will be used in this widget.
Bg Color | status and process. Set what controls the background color of the task. Status sets the task color to be the same as the status color. Process mode sets the task color to be the same color of the process as set in the Workflow Editor. |
Status Color | status and process. Set what controls the background color of the status drop down. Status sets the status drop down color to be the same as the status color. Process mode sets the status drop down color to be the same color of the process as set in the Workflow Editor. |
Context Color | status and process. Set what controls the background color of the context grid. Status sets the context grid color to be the same as the status color. Process mode sets the context grid color to be the same color of the process as set in the Workflow Editor. |
Text Color | Specifies the color of the task text using a color swatch. |
Show Process | True or false. Displays the process of the task within the column. |
Show Context | True or false. Displays the context of the task within the column. |
Show Dates | True or false. Displays the time frame for the task. The schedule will display the start and end date. |
Show Assigned | True or false. Displays the assigned user to the task. |
Show Track | True or false.. Displays a button on each task which displays the last status and the user who changed it. |
Show Labels | True or false. Displays the label of the pipeline’s process. |
Show Border | all, one-sided, none. All displays a border around each task. One-sided displays a border around one one side of the task. None hides the border. |
Show Current Pipeline Only | True or false. Displays tasks for the current pipeline only. |
Show Task Edit | True or false. Displays a button which pops-up a window to edit the task info. |
Task Edit view | Specify the Task view by which to edit the task information. |
Task Filter | panel, vertical, horizontal: Layout orientation to display the list of tasks. |
Layout | context only or process only: Displays only tasks for either the context or the process. |
Edit Status | True or false. Allows the user to open the status drop down selection box for the status to change it. |
Edit Assigned | True or false. Allows the user to open the status drop down selection box for the assigned user to change it. |
Advanced
<element name='task_status_edit'> <display class='tactic.ui.table.TaskElementWdg'> <show_context>true</show_context> <show_assigned>true</show_assigned> <show_dates>true</show_dates> <edit>true</edit> </display> <action class='tactic.ui.table.TaskElementCbk'/> </element>
Description
The Link Element Widget facilitates creation of a hyperlink. Clicking on the link button opens the hyperlink in a new tab in the web browser.
Info
Name | Link Element |
Common Title | Link |
Class | Link |
TACTIC Version Support | 3.0.0 |
Required database columns | none |
Usage
Go into edit mode for the Link column. Specify the full URL to a hyperlink, such as: http://support.southpawtech.com.
Save the data and refresh the view.
Click on the link icon and the link to the web page will be opened in a new tab.
Implementation
The Link Element Widget can be created using the Create New Column and specifying: Display → Widget → Link.
Options
The ability to specify a customize icon to appears in the row.
Advanced
<element name="link" title="link" edit="true" color="false"> <display widget="link"/> </element>
To submit an official support ticket to the Southpaw Support Team you will need a TACTIC Ticketing Account. Ticketing accounts are typically setup for users by Southpaw as part of official TACTIC support. Contact your TACTIC representative for more information.
You may also visit the Southpaw Technology Support site at:
Note
If you do not already have an account for the support site, you may sign up from the login page. Accounts on the support site need to be verified by the support team. This typically takes about 24 hours
.
Description
The Work Element Widget is used for accessing the checkin and checkout tool needed to handle a task assigned. After a task is assigned, an artist can go to the "My Tasks" or any other task page where there is a "Work" column which will expand to this widget. You can carry out serveral typical functions related to check-in and check-out in the sub tabs that open. You can even customize what tabs are opened when the work button is clicked on.
Name | Work |
Class | tactic.ui.table.WorkElementWdg |
Category | Table Element Widget |
Supported Interfaces | TableLayoutWdg |
TACTIC Version Support | 3.5.0 |
Required database columns | none |
Usage
When clicked on, it opens up a new Work area tab with 3 sub tabs underneath which comprise all the functions an artitst would need when assigned a task. He can enter notes, change task status, review check-in history, check in, and check out files.
The General Check-in Widget appears in the Check-in sub tab. You can click "Browse" here to select the file to be checked in. The is_current checkbox in Options can be used to make a snapshot current on checking in. The link checkbox, when checked, links the sandbox directory to the process tied to the task. It makes it easy for an artist to jump to a different process and checks out their snapshots into the current sandbox associated with the task. Otherwise, if you check out a file from the model process, it will be copied to the model sandbox folder.
Options
checkout_panel_script_path | Deprecated in 3.5. Use the tab_config_<> method to set up custom checkout tab |
checkout_script_path | A custom check-out script path you can specify to override the default check-out script. The default check-out script checks out everything under the selected snapshot. Refer to Example 4. |
validate_script_path | A script path pointing to a JS script that is run before the actual check-in. If it throws an error using "throw(<error message>)", the check-in will not initiate. You can also use it to run some client-side preprocessing of the file or directory. |
transfer_mode | Upload, copy, move, preallocate are supported. preallocate can only be used if the client machine has direct disk write access to the TACTIC asset repo. It skips the need to hand off the files in the handoff directory. copy is recommended for most situation when users are usually granted only read access to the TACTIC asset repo. |
mode | Sequence, file, dir, and add are supported. sequence is for file sequence checkin; file is for single file checkin, dir is for directory checkin and add if for appending file or dir to an existing snapshot. If not specified, multiple selections will be available for the user to choose. Note: upload transfer mode only supports single file or file sequence check-in. |
checkin_panel_script_path | Deprecated in 3.5. Use the tab_config_<> method to set up custom checkin tab |
checkin_script_path | A custom checkin script path you can specify to override the default check-in script. This can be used in conjunction with the validate_script_path. |
process | If set, the process specified will be pre-selected when the General Checkin Widget is drawn, |
lock_process | If set to true, the user will not be able to choose a different process during check-in on the General Checkin-in Widget |
checkin_relative_dir | If specified, e.g. WIP, it is appended to the current sandbox directory and preselcted as the directory to be checked in. It’s applicable to Direcotry-type checkin |
checkin_ui_options | It applies to the check-in options of the CheckinWdg. Supported attribute at the moment is "is_current" e.g. {"is_current":"false"} would make all check-ins non-current. {"is_current":"optional"} would make the checkbox unchecked by default. Not specifiying it would render the option available to the user to choose at the check-in time. |
show_versionless_folder | If set to true, it displays the latest and current versionless folders. |
Implementation
The following defines the default "Work" element. It looks a bit complicated but in most cases, you would just need to simply change the different options available through "Edit Column Definition":
<element name="work" title="Work on Task"> <display class="tactic.ui.table.WorkElementWdg"> <transfer_mode>upload</transfer_mode> <cbjs_action> var tbody = bvr.src_el.getParent(".spt_table_tbody"); var element_name = tbody.getAttribute("spt_element_name"); var search_key = tbody.getAttribute("spt_search_key"); var checkin_script_path = bvr.checkin_script_path; var checkin_ui_options = bvr.checkin_ui_options; var validate_script_path = bvr.validate_script_path; var checkout_script_path = bvr.checkout_script_path; var checkin_mode = bvr.mode; var transfer_mode = bvr.transfer_mode; var sandbox_dir = bvr.sandbox_dir; var lock_process = bvr.lock_process; var server = TacticServerStub.get(); var code = server.eval( "@GET(parent.code)", {search_keys: search_key} ); spt.tab.set_main_body_tab(); spt.tab.add_new(); var kwargs = { 'search_key': search_key, 'checkin_script_path': checkin_script_path , 'checkin_ui_options': checkin_ui_options , 'validate_script_path': validate_script_path , 'checkout_script_path': checkout_script_path, 'mode': checkin_mode , 'transfer_mode': transfer_mode, 'sandbox_dir': sandbox_dir, 'lock_process': lock_process } var title = "Task: " + code; var class_name = "tactic.ui.tools.sobject_wdg.TaskDetailWdg"; spt.tab.load_selected(search_key, title, class_name, kwargs); </cbjs_action> <icon>WORK</icon> </display> </element>
The following defines a different usage of it using copy trasnfer mode, a custom checkout script and a custom validating checkin script. The value of the two script paths are the script_path you have saved in the Script Editor. lock_process is set to false. To enable these options, you can do it in the context menu "Edit Column Definition" and set the following:
checkout_script_path: checkout/all_processes validate_script_path: checkin/validate_frames transfer_mode: copy lock_process: false
The following shows a way to customize what the small check-out button does in the checkout_tool view. In widget config, we will set the column definition for the element checkout for the "sthpw/snapshot" search type. It can be accessed through "Edit Column Definition".
checkout_script_path: checkout/checkout_tool_script
Script Samples
Example 1: checkin/validate_frames
var values = bvr.values; var file_path = values.file_paths[0]; var sk = values.search_key; var applet = spt.Applet.get(); var file_list = applet.list_dir(file_path); var server = TacticServerStub.get(); var st = 'prod/shot'; var shot = server.get_by_search_key(sk); var frame_count = parseInt(shot.frame_count, 10); for (var i=0; i <file_list.length; i++){ var base =spt.path.get_basename(file_list[i]); if ( base == 'FRAMES') { var frames = applet.list_dir(file_list[i]); if (frames.length != frame_count) { throw('Frames length in FRAMES [' + frames.length + '] folder does not match shot\'s frame count'); } } }
Example 2: checkout/all_processes. It illustrates how to implement a custom check-out that only checks out a portion of what has been checked in.
//back up the Work-in-progress folder function backup_WIP(bvr) { var sandbox_dir = bvr.sandbox_dir; var applet = spt.Applet.get(); var found_WIP = false; var dirs = applet.list_dir(sandbox_dir, 0); for (var k=0; k < dirs.length; k++){ if (/WIP$/.test(dirs[k])){ found_WIP = true; break; } } if (!found_WIP) { alert('WIP folder not found. Backing up of WIP folder aborted') } else { var server = TacticServerStub.get(); var folder = spt.path.get_basename(sandbox_dir); var date_obj = new Date(); var suffix = date_obj.getFullYear().toString() + spt.zero_pad((date_obj.getMonth() + 1).toString(), 2) + spt.zero_pad(date_obj.getDate().toString(), 2) + '_' + spt.zero_pad(date_obj.getHours().toString(), 2) + spt.zero_pad(date_obj.getMinutes().toString(),2); var parts = sandbox_dir.split(/[\/\\]/); sandbox_dir = sandbox_dir + '/WIP'; var backup_dir = parts.join('/') + '/WIP' + '_' + suffix; applet.copytree(sandbox_dir, backup_dir); //remove the contents of WIP applet.rmtree(sandbox_dir); applet.makedirs(sandbox_dir); } } // just checkout a subfolder named REF. if it's not found, just check out the // first subfolder function checkout_snapshot_table(bvr){ var top = bvr.src_el.getParent(".spt_checkin_top"); var table = top.getElement(".spt_table"); var search_keys = spt.dg_table.get_selected_search_keys(table); if (search_keys.length == 0) { alert('Please check the checkbox(es) to check out a version.'); } else if (search_keys.length > 1) { alert('Please check only 1 checkbox at a time. Multi-selection is' + ' only supported for Full Check-out Selected in the Gear menu.'); return; } spt.app_busy.show("Custom Check-out snapshots", "Copying to Sandbox..."); var server = TacticServerStub.get(); var top = bvr.src_el.getParent('.spt_checkin_top'); var sandbox_input = top.getElement('.spt_sandbox_dir'); if (sandbox_input) bvr.sandbox_dir = sandbox_input.value; for (var i =0; i < search_keys.length; i++) { checkout_snapshot(bvr, search_keys[i]); } spt.app_busy.hide(); } function checkout_snapshot(bvr, snapshot_key, downlevel) { var server = TacticServerStub.get(); try { var paths = server.get_all_paths_from_snapshot(snapshot_key); //var sandbox_dir = server.get_client_dir(snapshot_key,{mode:'sandbox'}); var sandbox_dir = bvr.sandbox_dir; var applet = spt.Applet.get(); for (var i = 0; i < paths.length; i++ ) { var path = paths[i]; var parts = path.split(/[\/\\]/); var dirs = applet.list_dir(path); var tar_dir = ''; for (var j=0; j < dirs.length; j++) { if ((/REF/i).test(dirs[j])) tar_dir = dirs[j]; } //just take the first one if REF is not found if (!tar_dir) { alert('REF not found. First subfolder is checked out'); tar_dir = dirs[0]; } var folder = spt.path.get_basename(tar_dir); var new_path = path + '/' + folder; var sand_paths = applet.list_dir(sandbox_dir, 0); for (var j=0; j< sand_paths.length; j++) { var dst_folder = spt.path.get_basename(sand_paths[j]); if (dst_folder == 'REF') { alert('REF folder already exists in [' + sandbox_dir + '] Please rename or remove it first.'); return; } } // the applet can decide between copy_file or copytree applet.copytree(new_path, sandbox_dir + "/" + folder); } } catch(e){ alert(spt.exception.handler(e)); } } backup_WIP(bvr); var down_level = 1; checkout_snapshot_table(bvr, down_level);
Example 3: Custom Checkout button callback passing a specific script for the Check-out Widget popup using display option "checkout_panel_script_path"
var class_name = 'tactic.ui.widget.CheckoutWdg'; var values = bvr.values; var search_key = values.search_key; var sandbox_dir = values.sandbox_dir; var process = values.process; var options = { 'show_publish': 'false', 'process': process, 'search_key': search_key, 'checkout_script_path': 'checkout/custom_checkout', 'sandbox_dir': sandbox_dir }; var popup_id ='Check-out Widget'; spt.panel.load_popup(popup_id, class_name, options);
Example 4: Custom check-out script for the small check-out button in the checkout_tool view. This can be used to customize a quick-checkout for the latest or current snapshot without opening the Check-out popup widget, using display option "checkout_script_path"
function checkout_snapshot(bvr) { var values = bvr.values; var snapshot_key = values.search_key; var context = values.context; var server = TacticServerStub.get(); // get the files for this snapshot, always get the latest // instead of relying on the last snapshot when the UI was drawn try { var paths = server.get_all_paths_from_snapshot(snapshot_key); //var sandbox_dir = server.get_client_dir(snapshot_key,{mode:'sandbox'}); // This one comes from values as the sandbox_dir is determined by // the snapshot only var sandbox_dir = values.sandbox_dir; var applet = spt.Applet.get(); for (var i = 0; i < paths.length; i++ ) { var path = paths[i]; var parts = path.split(/[\/\\]/); var dirs = applet.list_dir(path); var tar_dir = ''; for (var j=0; j < dirs.length; j++) { if ((/REF/i).test(dirs[j])) tar_dir = dirs[j]; } //just take the first one if REF is not found if (!tar_dir) { alert('REF not found. First subfolder is checked out'); tar_dir = dirs[0]; } var folder = spt.path.get_basename(tar_dir) var new_path = path + '/' + folder; var sand_paths = applet.list_dir(sandbox_dir, 0); for (var j=0; j< sand_paths.length; j++) { var dst_folder = spt.path.get_basename(sand_paths[j]); if (dst_folder == 'REF') { alert('REF folder already exists in [' + sandbox_dir + '] Please rename or remove it first to avoid mixing files.'); return; } } // the applet can decide between copy_file or copytree applet.copytree(new_path, sandbox_dir + "/" + folder); } } catch(e){ alert(spt.exception.handler(e)); } } checkout_snapshot(bvr);
Example 5: Custom checkin_script using display option "checkin_script_path". The default snapshot_type is file, if the file extension is .mov, the snapshot_type is set to mov.
var file_paths = bvr.values.file_paths; var description = bvr.values.description; var search_key = bvr.values.search_key; var context = bvr.values.context; var transfer_mode = bvr.values.transfer_mode var is_current = bvr.values.is_current; var path = file_paths[0] spt.app_busy.show("File Checkin", path); var snapshot_type = 'file'; if (path.test(/\\.mov$/)){ snapshot_type = 'mov'; } var server = TacticServerStub.get(); snapshot = server.simple_checkin(search_key, context, path, {description: description, mode: transfer_mode, is_current: is_current, snapshot_type:'mov'});
Description
Adding a Simple Search Filter at the top of a view helps filter the table for particular values on certain columns. A filter can be created using a Select Filter Element Widget or by running an expression using a Checkbox Filter Element Widget. (To set up the Select and Checkbox Filter Element Widgets, please refer to the setup docs by the same name.)
Implementation
Below are the steps to modify or add a Simple Search Filter to a view. The Simple Search View for the ticket list in the Scrum Project is used below as an example.
1) Go to the sidebar and open the view:
Admin Views → Project → Manage Side Bar
2) Look for the value in the following field:
Display Definition → Search → Simple Search View
3) Open the Widget Config under:
Admin Views → Project → Widget Config.
Filter by the search_type: scrum/ticket
Filter by the view found in the Simple Search View field of the Manage Side Bar view.
In the Scrum example with the tickets, we would search for the _view_named: simple_search_filter
Note
If the Simple Search View field is empty, TACTIC will look for the default Simple Search View filter named: custom_filter.
4) In the Widget Config entry, edit the config field:
In the example below, the following Checkbox Filter Element Widgets were added: my_tickets, beth_tickets and ted_tickets
<config> <simple_search_filter> <element name='assigned'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@GET(sthpw/login.login)</values_expr> <column>assigned</column> </display> </element> <element name='status'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values>new|open|in_dev|need_info|on_hold|need_validation|closed|invalid</values> <column>status</column> </display> </element> <element name='type'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@UNIQUE(@GET(scrum/ticket.type))</values_expr> <column>type</column> </display> </element> <element name='sprint'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@GET(scrum/sprint.title)</values_expr> <column>scrum/sprint.title</column> </display> </element> <element name='feature'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@GET(scrum/feature.title)</values_expr> <column>scrum/feature.title</column> </display> </element> <element name='product'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@GET(scrum/product.title)</values_expr> <column>scrum/feature.scrum/product.title</column> </display> </element> <element name='customer'> <display class='tactic.ui.filter.SelectFilterElementWdg'> <values_expr>@UNIQUE(@GET(scrum/ticket.customer_code))</values_expr> <column>customer_code</column> </display> </element> </simple_search_filter> </config>
Here are some miscellaneous date related examples:
<element name="dates"> <display class="tactic.ui.filter.DateFilterElementWdg"> <column>creation_date</column> </display> </element> <!-- this makes use of the status log to filter tasks completed or set to review since a particular date --> <element name='completed_date'> <display class='tactic.ui.filter.DateFilterElementWdg'> <column>sthpw/status_log['to_status','in','Complete|Review'].timestamp</column> </display> </element> <element name="date_range"> <display class="tactic.ui.filter.DateRangeFilterElementWdg"> <start_date_col>bid_start_date</start_date_col> <end_date_col>bid_end_date</end_date_col> <op>in</op> </display> </element>
For more examples of the Keyword Search, Select Filter, and Date Filter, refer to those docuements.
Note: To filter for data from another database, the cross_db attribute of the KeywordFilterElementWdg can be used.
<!-- in a task view, search for the shot's title attribute--> <element name="keywords"> <display class="tactic.ui.filter.KeywordFilterElementWdg"> <mode>keyword</mode> <column>vfx/shot.title</column> <cross_db>true</cross_db> </display> </element>
Description
The TextWdg is a basic form element in which a single line of text can be entered. (To enter multiple lines, use the TextAreaWdg instead.) It maps directly to the HTML text input. It can be used independently or as an edit element in the TableLayoutWdg or EditWdg.
Info
Name | Text Input |
Class | pyasm.widget.TextWdg |
TACTIC Version Support | 2.5.0 |
Required database columns | none |
Implementation
Basic example of a typical usage of a TextWdg
Options
size | Determine the width of the text widget. Default is "50". |
read_only | true |
Advanced
Simple example which displays text widget that is fully editable:
<element name='first_name'> <display class='pyasm.widget.TextWdg'/> </element>
A text widget that only allows integer input. The size is reduced to 5.
<element name='age'> <display class='pyasm.widget.TextWdg'> <size>5</size> </display> </element>
A simple example of the TextWdg in Python:
from pyasm.widget import TextWdg div = DivWdg() text_wdg = TextWdg("age") text_wdg.set_option("size", "20") div.add(text_wdg)
In a project, items (ie. files, assets) may be related to each other. For example, a car is built with various parts that can be identified separately but are all related to the same car. Another example can be found cinematic film production. The cinematic footage of one movie is commonly broken down into sequences and shots.
How do these relationships work in TACTIC? - Each sType is represented as a table in the database and each entry in the table represents an sObject. The relationships are created when storing matching data "properties" in each of the tables. In the example tables below there are "Sequence" and "Shot" sTypes. The "code" column matches the "sequence_code" column which illustrates which shot is related to which sequence.
code | description |
---|---|
SEQ001 | The first sequence |
SEQ002 | The first sequence |
sequence_code | code | description |
---|---|---|
SEQ001 | SEQ001_001 | Sequence one shot one |
SEQ001 | SEQ001_002 | Sequence one shot two |
SEQ002 | SEQ002_001 | Sequence two shot one |
In the Schema Editor, relationships are represented by lines connecting the nodes. When these connections are made, the columns used to relate the sTypes can be chosen in the Connection Editor.
To create a new connection, hover over a node and click-drag a connection to the desired node (sType).
Note
The direction of the arrow in the connection indicates from child to parent.
After a connection is made, the Connection Attributes editor will open to enable the choice of column relationships. It is also possible to create new columns from this editor.
Note
The yellow Switch button
in the middle of the tool toggles which node is the child and which one is the parent.
Note (discussion)
Description
The Notes Widget allows users to write notes for a particular item (sObject). This widget allows team members to exchange comments for a process by writing them in the Notes Widget. The notes are displayed chronologically with latest one appearing at the top. The complete history is displayed by default. It’s one of the common columns which can be added in any view for an sType. A similar note entry widget called the Note Sheet Widget, focuses more on the speed of entry rather than the display of the conversation.
Info
Name | Notes |
Class | tactic.ui.widget.DiscussionWdg |
Category | Table Element Widget |
Supported Interfaces | TableLayoutWdg |
TACTIC Version Support | 2.5 |
Required database columns | This widget interacts with the built in sthpw/note table |
Usage
To create a new note, select the New Note button.
This will switch the DiscussionWdg into insert mode where notes and context of the notes can be entered.
In most cases, the grouping for the notes is derived through selecting a context. This context is often chosen in relation to the context of a given task or snapshot (Checkin) for the same parent sObject. This then associates all tasks, notes and snapshots under a specific Search Object. This allows users to retrieve historical data for a Search Object through a context. This answers the question "What’s the history of this Asset from the design department?"
To navigate the history of the notes, click on a particular note and it will expand and display the full note.
Note
Depending on the configuration, the grouping (context) items will be grouped and separated by a group label represented as << label>>. In that case, selecting the group label will trigger a warning pop-up.
To unset a value, you can usually select the empty value with the label -- Select --.
Implementation
The Notes widget is a common column which can be added using the Column Manager. The item name is "notes". A "default" context is used in this simple implementation.
Options
context | a global context can be specified |
append_context | a context can be appended to the current list (deprecated) |
setting | A project setting can be used to drive the contexts. This provides the key of the project setting. |
append_setting | This serves the same purpose as setting but would append the contexts at the end |
include_submission | If set to true, it would include the notes for the submission (a child) of the current sObject. |
Advanced
<element name="discussion" edit="false"> <display class="pyasm.widget.DiscussionWdg"> <context>default</context> </display> </element>
Description
The Thumbnail Widget is available for most types by default as the preview tool for images which have been uploaded for preview and thumbnail purposes. An icon for the corresponding file type is displayed for non-image files.
Info
Name | Thumbnail Widget |
Common Title | Preview, Snapshot, Files |
TACTIC Version Support | 2.5.0 |
Required database columns | none |
Implementation
The Thumbnail widget is available in the common columns.
Options
script_path | Specify a script to control what UI it draws or what happens when the user click on the preview icon. Refer to it by this script path. |
detail_class_name | Specify the default behavior to open up a pop-up window but just with a different widget written in Python. |
icon_context | The context that the widget displays |
icon_size | Control the icon size by percentage (up to 100%) e.g. 30% |
min_icon_size | Minimum icon size (in pixels). |
latest_icon | If set to true, the icon displayed corresponds to the latest checkin in the checkin history. It will disregard the icon context designated for this search type. |
filename | If set to true, the file name of the linked file is displayed under the icon. |
original | If set to true, the link will point to the original file with the main file type checked in. Otherwise the scaled down web version of the file will be linked. This is only applicable to image-type files where an icon has been generated during a check-in. |
file_type | Whether to display the file type for download or not. |
detail | If set to false, clicking of the thumbnail will link the underlying picture instead of displaying the single asset view in a pop-up |
protocol | http(default) or file. The protocol under which the thumbnail link will open when being clicked on. When file is set, the default application is usually Windows explorer or at times Internet Explorer. file mode can alleviate the bandwidth usage on the web server when viewing large media files like Quick Time. |
redirect_expr | Works similarly as the redirect but in the form of expression. e.g. @SOBJECT(prod/sequence). If this display option is set for the ThumbWdg for prod/shot, it will display the icon of its sequence instead. |
TACTIC’s Custom Layout Editor provides users with the ability to completely customize the end user inteface. The HTML, Python, Styles, and Behaviours tabs offer the flexibility to dictate the appearance, functionality and actions of generated views. However, there are times where the appearance, functionality and actions need to be dynamic, changing depending on different events or conditions.
Custom URL Configuration encompasses these possibilities by offering the availability of variable options. Views can be modified by options that are set statically by the user and change dynamically with the system. These options can be inserted into code developed to define a view to perform a desired behaviour.
The Custom URL can be configured through Project Essentials under Custom URL. Entries can be added into the table with a specified URL path, pointing to a Custom Layout view to be modified, for example, and the associated HTML code under the Widget column to define the view.
image:media/Custom URL.png[image]
A list of options are available to the user to set within the HTML that defines a view from the Widget column. These options and associated descriptions and values are provided below. The first three options refer to the visibility and usability of the respective user interface element (sidebar, index and admin) when the Custom Layout component is drawn. The palette option establishes the overall color of these respective user interface elements.
Option | Description | Values |
sidebar | Determines whether the sidebar, as seen in the administrative layer, is available in the view. | true/false |
index | Determines whether the element will be displayed with the theming and configuration set up from the index URL. If set to "true", it will only work if there is an entry with a URL as "/index" in the Custom URL table. | true/false |
admin | Determines whether the element will be displayed with the theming and configuration of the administrative layer. | true/false |
palette | Determines the overall color theme of all of the tables and associated menus in the view. | aqua/aviator/bon noche/bright/dark/ silver/origami |
Two examples are shown to demonstrate how to statically set these options to configure a URL, as well as how to specify a view as the home or landing page of a TACTIC project.
Example 1: HTML Element Options
The example below is taking a specific view for a job established by the URL /job/JOB002 and setting the admin, sidebar and palette options inline with the definition of the element tag. Notice that the URL defined is only a portion of a full URL. The full URL would follow a format of http://<IP>/tactic/jobs/job/JOB002. Only the latter portion of the URL is required.
URL Column
/job/JOB002
Widget Column
<?xml version="1.0"?> <element admin='true' sidebar='false' palette='bright'> <display class='tactic.ui.panel.CustomLayoutWdg'> <search_type>my_project/my_sType</search_type> <view>my_view</view> </display> </element>
Example 2: Setting Home Page through URL
The user can set a custom view created in the Custom Layout Editor as the home or landing page when the user and all other users sign in. The HTML set in the Widget column can point to a specific view in the Custom Layout Editor to set as the home page. In this case, the display class would need to be defined as a Custom Layout Widget to accommodate for the use of a Custom Layout view.
Notice how the URL is set as "/index", which differs from the Custom Layout view in the HTML. The URL must be set as "/index" in order to have this view set as the home page.
URL Column
/index
Widget Column
<element name='index'> <display class='tactic.ui.panel.CustomLayoutWdg'> <view>custom_layout_folder/my_custom_view</view> </display> </element>
Dynamically Setting Options
The following examples will demonstrate how to dynamically set options. The first example will demonstrate how to configure multiple views using a dynamic URL following from Example 1 in the Statically Setting Options section. The second example will follow from the second example under the Statically Setting Options section. The Custom Layout view set as the home page will actually utilize mako with HTML in order to set the value of a variable to be used in the HTML. This variable is used to set the display class of the element.
Example 1: Configuring Multiple Views through a Dynamic URL
In Example 1 from the Statically Setting Options section, the view being modified was for a specific job. In this example, you can see that the same modifications can be applied to the views for all jobs. The {…} syntax allows for a variable value. In this case, the "code" variable can change. The job "code" defines the jobs in the project through an alphanumeric sequence, such as "JOB002". This variable syntax allows the URL to keep changing for all the jobs present in the project. This means that different jobs can appear in the same view as it will have the same HTML definition.
Notice how the display class is changed to a Table Layout as opposed to a Custom Layout Widget. This is just to demonstrate the different display classes available to the user as well.
URL Column
/job/\{code}
Widget Column
<?xml version="1.0"?> <element admin='true' sidebar='false' palette='bright'> <display class='tactic.ui.panel.TableLayoutWdg'> <search_type>my_project/my_sType</search_type> <view>my_view</view> </display> </element>
Example 2: Custom Layout Editor - Setting Element Display Class in HTML with Changing Mako Variable Value
The focus on this example will be the utilization of Mako and HTML in the Custom Layout Editor for the view defined in Example 1 of the Statically Setting Options section. The code from Example 1 of the Statically Setting Options section is shown again here for reference.
The Mako code is set up to determine whether a search key is existent in TACTIC. What this means is TACTIC is aware if an entry with a specific ID already exists in the sType table. This code is utilizing that ability and checking whether that entry does already exist. The entry’s existence determines what the display_widget variable will be set to.
In the HTML for the "last_name" element, the display class is variable as indicative of the syntax "${…}", which wraps the variable display_widget. Based on the existence of the search key, the display class of the "last_name" element will be either a text input widget or a lookahead text input widget.
URL Column
/index
Widget Column
<element name='index'> <display class='tactic.ui.panel.CustomLayoutWdg'> <view>custom_layout_folder/my_custom_view</view> </display> </element>
HTML Tab in Custom Layout Editor for custom_layout_folder/my_custom_view View
<div> <div> <% sType2_key = kwargs.get("search_key") or "" if sType2_key: display_widget = "tactic.ui.input.TextInputWdg" else: display_widget = "tactic.ui.input.LookAheadTextInputWdg" %> </div> <table> <tr> <td>Last Name</td> <td class="spt_element"> <element name="last_name"> <display class="$\{display_widget}"> <search_type>my_project/my_sType</search_type> <column>my_view2</column> <search_key>$\{sType2_key}</search_key> <filter_search_type>my_project/my_sType</filter_search_type> <value_column>id</value_column> <current_value_column>id</current_value_column> </display> </element> </td> </tr> </div>
Description
The TableLayoutWdg is the primary widget used to layout tabular data. It is primarily driven by the widget configuration. The TableLayoutWdg has the ability to display complex widgets inside each cell, to inline edit the data and to color code cells. It is the widget that is most often used to display information within the TACTIC.
Info
Name | Table Layout |
Class | tactic.ui.panel.TableLayoutWdg |
TACTIC Version Support | 2.5.0 \+ |
Required database columns | none |
Implementation
The TableLayoutWdg makes use of "views" which are defined in the widget config for each project. When the Table is loaded as part of an interface, a view configuration is passed into it which defines which columns and widgets should be displayed in the view. Typically, these view configurations are automatically saved in the background when a user saves a view from within the TACTIC interface. The table itself provides the ability to add, remove, rearrange, resize and group columns which can then be saved out often as links in the sidebar.
The following shows a simplified version for an "asset tracking" view as saved in the background widget config.
<config> <asset_tracking layout="TableLayoutWdg" > <element name="preview" width="74px"/> <element name="asset_category_code" width="64px"/> <element name="code" width="61px"/> <element name="title" width="121.883px"/> <element name="description" width="276.75px"/> <element name="keywords" width="253.367px"/> <element name="general_checkin" width="27px"/> <element name="history" width="42px"/> <element name="task_edit" width="29px"/> <element name="task_status_edit" width="223.167px"/> </asset_tracking> </config>
The widget configuration is an XML document. In this example, it defines an "asset_tracking" view with elements (preview, asset_category, code, title, description, keywords, etc…).
To draw what to display, TableLayoutWdg looks at the list of elements defined in the widget config and draws a column for each element. TACTIC then draws a row for each item that was either retrieved from a search, an expression or by supplied items. Each cell in the table represents an item being drawn by the defined element for a given column.
While the top widget configuration defines the list of elements to draw the columns, the exact definition of each element do not necessarily appear here. There are a number of views which define an element. Some of these elements may be defined inline or they may be defined elsewhere. There is a set hierarchy which the TableLayoutWdg looks for to find the definition of a particular element.
The hierarchy which TableLayoutWdg looks to find the definition for an element is as follows:
The third and fourth locations only apply to predefined types that are shipped with TACTIC. All custom types will only use the first two.
Options
search_type | Defines the type that this table will be displaying. It is used both for finding the appropriate widget config and for handling search (if necessary). Defaults to "table". |
view | Defines the view that this table will displaying. It used to find the appropriate widget config to display the table. |
do_search | By default, the TableLayoutWdg will handle the search itself. However, certain widgets may wish to turn this functionality off because they are supplying the search (internally used by ViewPanelWdg) |
order_by | Add an explicit order by in the search |
expression | Use an expression to drive the search. The expression must return items. |
parent_key | Set a specific parent for the search |
width | Define an initial overall width for the table |
show_row_select | Flag to determine whether or not to show row_selection |
show_gear | Flag to determine whether or not to show the gear menu. |
show_insert | Flag to determine whether or not to show the insert button. |
insert_mode | aux |
inline | pop-up |
none - set the insert mode of the table | search_limit |
An overriding search limit. A value < 0 means no limit affecting the search | config_xml |
Explicitly define the widget config | element_names |
Advanced
Very often, the TableLayoutWdg is not used directly, but is used through the ViewPanelWdg, which combines the TableLayoutWdg with the SearchWdg. Using ViewPanelWdg will provide all the functionality in a table view
Using the TableLayoutWdg does provide a simpler view if the search is already known,
This simple example shows the login table and the objects are explicitly given.
from tactic.ui.panel import TableLayoutWdg div = DivWdg() table = TableLayoutWdg(search_type='sthpw/login', view='table') sObjects = Search("sthpw/login").get_sObject() table.set_sObjects(sObjects) div.add(table)
An expression can be set for the search as well.
from tactic.ui.panel import TableLayoutWdg div = DivWdg() expression = "@SOBJECT(sthpw/login)" table = TableLayoutWdg(search_type='sthpw/login', view='table',expression=expression) div.add(table)
This example embeds the login table with a "table" view in a CustomLayoutWdg.
<config> <login> <html> <h1>This is the login table</h1> <element name='login_table'/> </html> <element name='login_table'> <display class='tactic.ui.panel.TableLayoutWdg'> <search_type>sthpw/login</search_type> <view>table</view> <expression>@SOBJECT(sthpw/login)</expression> </display> </element> </login> </config>
The widget config views determine how the TableLayoutWdg draws itself. There are a few custom attributes that a view can define. The view can define many parts of how the TableLayoutWdg is displayed. The following hides the "insert" button and makes each of the cells non-editable. These attributes are useful for reports which are generally not editable.
<?xml version="1.0" encoding="UTF-8"?> <config> <simple insert='false' edit='false'> <element name="preview"/> <element name="code"/> <element name="name"/> <element name="description"/> </simple> </config>
Drop Item
Description
Facilitates drag-and-drop of an item between 2 views. For example, drag a user from one view and drop it into a user group.
Info
Name | Drop Element Widget |
Common Title | Drop Element Widget |
Class | tactic.ui.table.DropElementWdg |
TACTIC Version Support | 3.0.0 |
Required database columns | none |
Usage
For example, in the Shot Planner view, individual assets can be added to a shot by simply dragging the asset from one view and dropping it onto the shot in another view. Once the asset is dropped onto the shot, the asset will appear in the column with a "NEW" flag. Hit the save button in the shot view to preserve the changes.
Options
Accepted Drop Type | The acceptable sType that can be clicked on to be dragged and dropped onto another type. For example, sType is vfx/asset. |
Instance Type | For the item that is being dragged, it is the sType that the item can be dropped onto. For example, sType is vfx/asset_in_shot" |
Cbjs Drop Action | The call back JavaScript to run each time an item is dropped into the column. |
Display Expr | The expression to run to display in view mode. For example "@" |
Implementation
A many-to-many relationship between the 2 types needs to be created in the Schema Editor. By convention, the "join" node that need to be created to connect the 2 types should be named: "<sType1>_in_<sType2> ". For example, for the join node named: "asset_in_shot". The "asset_in_shot" node stores the data representing the relationship between the asset and which shot it appears in.
The view where the item to be dropped onto the Drop Element column of, can exist in a custom layout table or a view opened in a new window within the TACTIC session.
<element name="asset_drop" width="333px" edit="false"> <display class="tactic.ui.table.DropElementWdg"> <instance_type>vfx/asset_in_shot</instance_type> <accepted_drop_type>vfx/asset</accepted_drop_type> <css_background-color>#425952</css_background-color> </display> <action class="tactic.ui.table.DropElementAction"> <instance_type>vfx/asset_in_shot</instance_type> </action> </element>
Examples
Example 1: implementation of "asset_in_shot', where an asset can be drag and dropped onto a shot:
<element name="asset_drop" width="333px" edit="false"> <display class="tactic.ui.table.DropElementWdg"> <instance_type>vfx/asset_in_shot</instance_type> <accepted_drop_type>vfx/asset</accepted_drop_type> <css_background-color>#425952</css_background-color> </display> <action class="tactic.ui.table.DropElementAction"> <instance_type>vfx/asset_in_shot</instance_type> </action> </element>
Example 2: implementation of "user_in_group', where a user can be drag and dropped onto a group:
<element name="users"> <display class="tactic.ui.table.DropElementWdg"> <css_background-color>#425952</css_background-color> <instance_type>sthpw/login_in_group</instance_type> <accepted_drop_type>sthpw/login</accepted_drop_type> </display> </element>
Setup Introduction
The role of Setting up TACTIC is to configure and maintain the structure of the TACTIC projects.
These responsibilities may include:
This section will help you to understand how to approach this setup and configure your system properly.
Description
The Checkbox Filter Element Widget appears as a check box which activates filteringm when checked. This widget provides a convenient way to perform more complex search operations.
Info
Name | Checkbox Filter Element Widget |
Class | tactic.ui.filter.CheckboxFilterElementWdg |
TACTIC Version Support | 3.7+ |
Required database columns | none |
Options
Titles for Checkbox Filter Element. For example:
titles | <display class=tactic.ui.filter.CheckboxFilterElementWdg> <titles>Active|Pending|Closed</titles> </display> |
options | <options>my_tickets|beth_tickets|ted_tickets</options> <my_tickets>@SOBJECT(scrum/ticket[assigned,$LOGIN])</my_tickets> <beth_tickets>@SOBJECT(scrum/ticket[assigned,beth])</beth_tickets> <ted_tickets>@SOBJECT(scrum/ticket[assigned,ted])</ted_tickets> |
Implementation
Specify (or look up) the name of the Simple Search View under Admin Views → Project → Manage Side Bar → Simple Search View.
In the example below, the Simple Search View is named: simple_search_view
Look up and edit that simple search view in the Widget Config. Use the following XML code as an example of what to add to the config:
<config> <simple_search_view> <element name='dynamic'> <display class='tactic.ui.filter.CheckboxFilterElementWdg'> <options>asset_category_3d</options> <asset_category_3d>@SOBJECT(project/asset['asset_category_code','3d'])</asset_category_3d> </display> </element> </simple_search_view> </config>
For the above example, this filter returns results where the asset_category_code is: 3d
Examples
Below is an example of adding 3 check box filters: a filter to search for tickets that belong to the currently logged in user, the user beth and the user ted. Notice that the options are pipe | separated.
<config> <simple_search_view> <element name='mine'> <display class='tactic.ui.filter.CheckboxFilterElementWdg'> <options>my_tickets|beth_tickets|ted_tickets</options> <my_tickets>@SOBJECT(scrum/ticket['assigned',$LOGIN])</my_tickets> <beth_tickets>@SOBJECT(scrum/ticket['assigned','beth'])</beth_tickets> <ted_tickets>@SOBJECT(scrum/ticket['assigned','ted'])</ted_tickets> </display> </element> </simple_search_view> </config>
Advanced
Below is an example of filtering for the condition of having one or more icons snapshots related to shots:
<config> <simple_search_view> <element name='dynamic'> <display class='tactic.ui.filter.CheckboxFilterElementWdg'> <options>some_icon</options> <some_icon>@SOBJECT(prod/shot.sthpw/snapshot['context','icon']['project_code','sample3d'].prod/shot)</some_icon> </display> </element> </simple_search_view> </config>
TACTIC Security
All information in TACTIC goes through a series of security checks that are built into the lowest level of the software. The security architecture is a rules-based system where an access request to any piece of information must satisfy all the rules before the user gains access to it.
Each user has a login. User logins are assigned to groups, and each group can have a number of access rules attached to it. These rules determine what a user is permitted to see and do in TACTIC. At the base level, these permissions are XML structured rules that are stored in the "access_rules" property of a group SObject. Although inserting these rules directly into the XML code allows for the most flexibility for the project manager, there are various other aspects of the TACTIC interface that can also assist in the rule creation process.
Managing Rules
The "groups" search type contains a property (available in the column manager) named "Global rules." When this property is included in the view, a click-able button is available to load the global rules pop-up. This pop-up provides several predefined global access rules that can be applied to the group:
View Side Bar | View access for the complete side bar. |
View Site Admin | Allow access to see the "Site Admin" section of the side bar. |
View Script Editor | Access to the Script Editor |
View Side Bar Schema | Allow access to the schema section of the side bar. |
View and Save My Views | Save personal My Views |
View Private Notes | Allow viewing of private notes. |
View Column Manager | Allow viewing of the column manager |
Create Projects | Allow creating of new projects. |
Import CSV | Import CSV Files. |
Retire and Delete | Allow the ability to retire and delete in the right-click context menu.. |
To customize the options for these rules, click the edit icon in the Global Permissions column for the desired group. From the rule selection pop-up that appears, select one of the options. When you click the save button, they are committed to the access rule XML for the chosen group.
Side bar Manager Security
You can select which groups can see each of the links in the TACTIC side bar manager.
The Element Detail window lists all groups in the system. Check any group to allow access (or uncheck to deny access). When you click the Save Definition button, your changes are saved to each group’s "access_rules" property. To view your changes in the XML code for any of the groups, navigate to a group view which has the "access_rules" property column.
Expression Value Element
Description
The Expression Value Element widget accepts a TACTIC Expression as the input and displays the evaluated expression as the output.
Info
Name | Expression Value Element Widget |
Class | expression_value |
TACTIC Version Support | 2.5.0 |
Required database columns | Yes, a database column by the same name. |
Usage
For example, we can dynamically display the number of login names in the login table. This would be an example of an absolute expression because the expression does not take into input any data from the row the field is on. A relative expression has access to the row and table information that the row the expression is on.
Note
The difference between an absolute expression and a relative expression:
-an absolute expression does not take into input any data from the row or table that the field exists on
-a relative expression has access to the row and table information that the field exists on
Implementation
Go into edit mode for the Expression Value Element widget. Input an absolute TACTIC expression as the value.
In display mode, this widget will display the result of the evaluation of the expression.
Options
There are no options available for this widget.
Example 1
For example, enter the following absolute TACTIC Expression as the value for the Expression Value Element widget:
@COUNT(sthpw/snapshot.sthpw/file)
In display mode, this widget will evaluate the expression and display the count of the number snapshot files in the database.
Example 2
For example, enter the following absolute TACTIC Expression as the value for the Expression Value Element widget:
@COUNT(sthpw/login.sthpw/login)
In display mode, this widget will evaluate the expression and display the count of the number of logins in the login table.
Example 3
For example, enter the following absolute TACTIC Expression as the value for the Expression Value Element widget:
@GET(sthpw/task["context = 'model'"].code)
In display mode, this widget will evaluate the expression and display the code for all the tasks where the context is model.
Gantt Description
The Gantt widget has the capability of displaying all projects schedules along with sequences and tasks schedules. With the widget you can switch between weeks to months view. This widget can be utilized and edited in multiple different ways. It also displays the start and end date along with the amount of days.
Info
Name | Calendar Gantt Widget |
Class | GanttWdg |
Category | Common Columns |
Supported Interfaces | TACTIC Version Support |
2.6.0+ | Required database columns |
Usage
There are many ways to edit the Gantt Widget. You can also edit what part of the month, week or year of the schedule to view. Clicking on the header date of the Gantt Widget will toggle the different viewing options.
Above shows two different displays of viewing the range of the date. Clicking on the weeks will toggle to another viewing range.
The bars that show the schedule can also be edited using the UI. Hovering the mouse over the bars will popup a a window that will display the dates of the schedule.
The bars can also be editied by selecting the start and end dates and sliding the either end from the right to left. The first image below shows the end of the date stretched to May 14 and the second image shows the start date streched back to March 13.
The schedule bar can also move sideways while keeping the number of days constant by selecting the bar and shifting it from left to right.
The Gantt Widget can also be edited using multi selection. Whether it is changing the end date, start date or sliding the bars forward and backward, the Gantt Widget can hande it. Below are images of a few examples of having the sequences muli-selected and edited.
The Gantt Widget also has the capability of sliding the full time line by selecting the empty area of the widget and dragging the mouse left or right.
The Gantt Widget can be found under the column manager as task schedule.
Advanced
The following example illustrates a Gantt Widget that shows all tasks for a project, the schedule for all asset tasks, and the schedule for all shot tasks.
<element name='task_schedule'> <display class='tactic.ui.table.GanttElementWdg'> <options>[ { "start_date_expr": "@MIN(sthpw/task.bid_start_date)", "end_date_expr": "@MAX(sthpw/task.bid_end_date)", "color": "white", "edit": "true", "default": "true" }, { "start_date_expr": "@MIN(sthpw/task['search_type', '~', 'asset'].bid_start_date)", "end_date_expr": "@MAX(sthpw/task['search_type', '~', 'asset'].bid_end_date)", "color": "red", "edit": "true", "default": "false" }, { "start_date_expr": "@MIN(sthpw/task['search_type', '~', 'shot'].bid_start_date)", "end_date_expr": "@MAX(sthpw/task['search_type', '~', 'shot'].bid_end_date)", "color": "blue", "edit": "true", "default": "false" } ]</options> </display> <action class='tactic.ui.table.GanttCbk'> <sobjects>@SOBJECT(prod/shot.sthpw/task)</sobjects> <options>[ { "prefix": "bid", "sobjects": "@SOBJECT(sthpw/task)", "mode": "cascade" }, { "prefix": "bid", "sobjects": "@SOBJECT(sthpw/task['search_type', '~', 'asset'])", "mode": "cascade" }, { "prefix": "bid", "sobjects": "@SOBJECT(sthpw/task['search_type', '~', 'shot'])", "mode": "cascade" } ]</options> </action> </element>
Note: There are 3 editable bars in the display options in the above example and therefore, there are 3 corresponding action options. The prefix action option assumes that the column in the table is named like <prefix>_start_date and <prefix>_end_date. If your column names are different, you would want to use the action_option "start_date_col" and "end_date_col" with the full column name as the value.