diff --git a/data/creators/job-role.mod/job-role.css b/data/creators/job-role.mod/job-role.css
new file mode 100644
index 00000000..5147e085
--- /dev/null
+++ b/data/creators/job-role.mod/job-role.css
@@ -0,0 +1,40 @@
+
+.JobRoleInspector {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ padding: 12px 8px;
+ background: white;
+
+
+ .field {
+ height: 100%;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ align-items: start;
+ background: white;
+ flex-direction: column;
+
+ >.field-label {
+ font-size: 14px;
+ font-weight: bold;
+ color: #666;
+ margin-top: 10px;
+
+ &:first-child {
+ margin-top: 0;
+ }
+ }
+ }
+
+ .line-item {
+ font-size: 12px;
+ color: #333;
+ margin-left: 10px;
+ padding: 2px 0;
+ }
+
+}
+
+
diff --git a/data/creators/job-role.mod/job-role.html b/data/creators/job-role.mod/job-role.html
new file mode 100644
index 00000000..36e26c25
--- /dev/null
+++ b/data/creators/job-role.mod/job-role.html
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
Editing
+
+
Context
+
+
Processes
+
+
+
+
+
diff --git a/data/creators/job-role.mod/job-role.js b/data/creators/job-role.mod/job-role.js
new file mode 100644
index 00000000..504ad220
--- /dev/null
+++ b/data/creators/job-role.mod/job-role.js
@@ -0,0 +1,17 @@
+var Component = require("mod/ui/component").Component;
+
+const DataService = require("mod/data/service/data-service").DataService;
+
+
+exports.JobRole = class JobRole extends Component {
+
+
+
+ enterDocument(firstTime) {
+ if (firstTime) {
+ if (!this.data){
+ throw new Error("Role context is required for JobRole inspector");
+ }
+ }
+ }
+};
diff --git a/data/inspectors/job-role.mod/job-role.css b/data/inspectors/job-role.mod/job-role.css
new file mode 100644
index 00000000..9048affc
--- /dev/null
+++ b/data/inspectors/job-role.mod/job-role.css
@@ -0,0 +1,66 @@
+
+.JobRoleInspector {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ padding: 12px 8px;
+ background: white;
+
+
+ .field {
+ width: 100%;
+ height: 100%;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ align-items: start;
+ background: white;
+ flex-direction: column;
+ >.field-label {
+ font-size: 14px;
+ font-weight: bold;
+ }
+ > .field-label-row {
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ >.field-label {
+ font-size: 14px;
+ font-weight: bold;
+ margin-top: 10px;
+
+ &:first-child {
+ margin-top: 0;
+ }
+ }
+ }
+ }
+
+
+
+ .line-item {
+ font-size: 12px;
+ color: #333;
+ margin-left: 10px;
+ padding: 2px 0;
+ }
+
+ .field-value {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ > .line-item {
+ min-height: 48px;
+ width: 90%;
+ text-overflow: ellipsis;
+ overflow: hidden;
+
+ }
+ }
+
+}
+
+
diff --git a/data/inspectors/job-role.mod/job-role.html b/data/inspectors/job-role.mod/job-role.html
new file mode 100644
index 00000000..641c0626
--- /dev/null
+++ b/data/inspectors/job-role.mod/job-role.html
@@ -0,0 +1,166 @@
+
+
+
+
+
+
+
+
+
+
Title
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/data/inspectors/job-role.mod/job-role.js b/data/inspectors/job-role.mod/job-role.js
new file mode 100644
index 00000000..756552db
--- /dev/null
+++ b/data/inspectors/job-role.mod/job-role.js
@@ -0,0 +1,45 @@
+var Component = require("mod/ui/component").Component;
+
+const Deliverable = require("../../model/deliverable").Deliverable;
+const Process = require("../../model/process").Process;
+const JobRoleCollaboration = require("../../model/job-role-collaboration").JobRoleCollaboration;
+
+
+exports.JobRole = class JobRole extends Component {
+
+
+
+ enterDocument(firstTime) {
+ if (firstTime) {
+ if (!this.data){
+ throw new Error("Role context is required for JobRole inspector");
+ }
+ }
+ }
+
+ handleAddProcessAction() {
+ if (!this.data.processes) {
+ this.data.processes = [];
+ }
+ this.data.processes.push(this.application.mainService.createDataObject(Process));
+ }
+ handleAddCollaborationAction() {
+ if (!this.data.collaborations) {
+ this.data.collaborations = [];
+ }
+ this.data.collaborations.push(this.application.mainService.createDataObject(JobRoleCollaboration));
+ }
+ handleAddDeliverableAction() {
+ if (!this.data.deliverables) {
+ this.data.deliverables = [];
+ }
+ this.data.deliverables.push(this.application.mainService.createDataObject(Deliverable));
+ }
+
+ handleAddResponsibilityAction() {
+ if (!this.data.responsibilities) {
+ this.data.responsibilities = [];
+ }
+ this.data.responsibilities.push("");
+ }
+};
diff --git a/data/model/job-role-cascading-list-ui-descriptor.mjson b/data/model/job-role-cascading-list-ui-descriptor.mjson
new file mode 100644
index 00000000..280b1868
--- /dev/null
+++ b/data/model/job-role-cascading-list-ui-descriptor.mjson
@@ -0,0 +1,9 @@
+{
+ "root": {
+ "prototype": "mod/core/meta/user-interface-descriptor",
+ "values": {
+ "cascadingListItemHeaderRightCollectionNameExpression": "'Add'",
+ "cascadingListItemFooterMiddleCollectionNameExpression": "length + ' item' + (length == 1 ? '' : 's')"
+ }
+ }
+}
diff --git a/data/model/job-role-ui-descriptor.mjson b/data/model/job-role-ui-descriptor.mjson
new file mode 100644
index 00000000..48169ffa
--- /dev/null
+++ b/data/model/job-role-ui-descriptor.mjson
@@ -0,0 +1,18 @@
+{
+ "root": {
+ "prototype": "mod/core/meta/user-interface-descriptor",
+ "values": {
+ "inspectorComponentModule": {
+ "%": "../inspectors/job-role.mod"
+ },
+ "creatorInspectorComponentModule": {
+ "%": "../creators/job-role.mod"
+ },
+ "collectionNameExpression": "'Role'",
+ "collectionInspectorComponentModule": {
+ "%": "mod/ui/list.mod"
+ },
+ "nameExpression": "name"
+ }
+ }
+}
\ No newline at end of file
diff --git a/data/model/job-role.mjson b/data/model/job-role.mjson
index 117f6269..17bcd044 100644
--- a/data/model/job-role.mjson
+++ b/data/model/job-role.mjson
@@ -20,8 +20,15 @@
"%": "./job-role"
},
"object":{"@": "JobRole"},
- "parent":{"@": "RoleDescriptor"}
-
+ "parent":{"@": "RoleDescriptor"},
+ "userInterfaceDescriptorModules": {
+ "*": {
+ "%": "./job-role-ui-descriptor.mjson"
+ },
+ "mod/ui/cascading-list.mod": {
+ "%": "./job-role-cascading-list-ui-descriptor.mjson"
+ }
+ }
}
},
"JobRole": {