snow-flow 2.9.9 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mcp.json +13 -141
- package/.mcp.json.template +11 -25
- package/README.md +18 -0
- package/claude-flow +81 -0
- package/claude-flow.bat +18 -0
- package/claude-flow.config.json +20 -0
- package/claude-flow.ps1 +24 -0
- package/dist/agents/index.d.ts +3 -10
- package/dist/agents/index.js +10 -50
- package/dist/agents/queen-agent.d.ts +0 -2
- package/dist/agents/queen-agent.js +25 -42
- package/dist/cli.js +1 -1
- package/dist/mcp/servicenow-automation-mcp.js +10 -10
- package/dist/mcp/servicenow-deployment-mcp.js +1050 -169
- package/dist/mcp/servicenow-development-assistant-mcp.js +13 -65
- package/dist/mcp/servicenow-integration-mcp.js +10 -10
- package/dist/mcp/servicenow-machine-learning-mcp.js +15 -15
- package/dist/mcp/servicenow-operations-mcp.js +23 -23
- package/dist/mcp/servicenow-platform-development-mcp.js +9 -9
- package/dist/mcp/servicenow-reporting-analytics-mcp.js +11 -11
- package/dist/mcp/servicenow-security-compliance-mcp.js +11 -11
- package/dist/mcp/servicenow-update-set-mcp.js +9 -9
- package/dist/mcp/shared/reliable-memory-manager.d.ts +78 -0
- package/dist/mcp/shared/reliable-memory-manager.js +268 -0
- package/dist/mcp/snow-flow-mcp.js +341 -87
- package/dist/queen/agent-factory.d.ts +4 -2
- package/dist/queen/agent-factory.js +72 -25
- package/dist/services/tensorflow-ml-service.d.ts +105 -0
- package/dist/services/tensorflow-ml-service.js +456 -0
- package/dist/services/widget-deployment-service.d.ts +107 -0
- package/dist/services/widget-deployment-service.js +332 -0
- package/dist/utils/file-storage-fallback.d.ts +62 -0
- package/dist/utils/file-storage-fallback.js +289 -0
- package/dist/utils/mcp-singleton-enforcer.d.ts +36 -0
- package/dist/utils/mcp-singleton-enforcer.js +201 -0
- package/dist/utils/mcp-timeout-fix.d.ts +53 -0
- package/dist/utils/mcp-timeout-fix.js +221 -0
- package/memory/agents/README.md +31 -0
- package/memory/claude-flow-data.json +1 -1
- package/memory/sessions/README.md +1 -1
- package/package.json +4 -2
- package/src/agents/README.md +192 -0
- package/src/health/README.md +161 -0
- package/src/memory/README.md +240 -0
- package/src/queen/README.md +403 -0
- package/src/schemas/deployment.schema.json +58 -0
- package/src/schemas/flow.schema.json +79 -0
- package/src/schemas/widget.schema.json +72 -0
- package/src/templates/base/application.template.json +45 -0
- package/src/templates/base/business_rule.template.json +33 -0
- package/src/templates/base/script_include.template.json +18 -0
- package/src/templates/base/table.template.json +64 -0
- package/src/templates/base/widget.template.json +25 -0
- package/src/templates/patterns/composite.incident-management.template.json +140 -0
- package/src/templates/patterns/widget.dashboard.template.json +238 -0
- package/src/templates/patterns/widget.datatable.template.json +292 -0
- package/dist/mcp/servicenow-graph-memory-mcp.js +0 -728
- package/servicenow/widgets/openai_incident_classifier/client_controller.js +0 -284
- package/servicenow/widgets/openai_incident_classifier/server_script.js +0 -314
- package/servicenow/widgets/openai_incident_classifier/style.css +0 -354
- package/servicenow/widgets/openai_incident_classifier/template.html +0 -167
- package/servicenow/widgets/openai_incident_classifier/widget.json +0 -86
- package/test-ml-improvements.sh +0 -76
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "script_include",
|
|
3
|
+
"name": "{{CLASS_NAME}}",
|
|
4
|
+
"description": "{{DESCRIPTION}}",
|
|
5
|
+
"config": {
|
|
6
|
+
"api_name": "{{API_NAME|CLASS_NAME}}",
|
|
7
|
+
"access": "{{ACCESS|public}}",
|
|
8
|
+
"active": true,
|
|
9
|
+
"script": "var {{CLASS_NAME}} = Class.create();\n{{CLASS_NAME}}.prototype = {\n initialize: function() {\n // Constructor\n },\n \n // Add your methods here\n {{METHOD_NAME|exampleMethod}}: function() {\n // Method implementation\n return true;\n },\n \n type: '{{CLASS_NAME}}'\n};"
|
|
10
|
+
},
|
|
11
|
+
"variables": {
|
|
12
|
+
"CLASS_NAME": "MyUtilityClass",
|
|
13
|
+
"DESCRIPTION": "Utility functions for ServiceNow",
|
|
14
|
+
"API_NAME": "MyUtilityClass",
|
|
15
|
+
"ACCESS": "public",
|
|
16
|
+
"METHOD_NAME": "exampleMethod"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "table",
|
|
3
|
+
"name": "{{TABLE_NAME}}",
|
|
4
|
+
"description": "{{TABLE_DESCRIPTION}}",
|
|
5
|
+
"config": {
|
|
6
|
+
"name": "{{TABLE_NAME}}",
|
|
7
|
+
"label": "{{LABEL}}",
|
|
8
|
+
"plural": "{{PLURAL}}",
|
|
9
|
+
"extends_table": "{{EXTENDS_TABLE|task}}",
|
|
10
|
+
"number_ref": {
|
|
11
|
+
"table": "{{TABLE_NAME}}",
|
|
12
|
+
"prefix": "{{PREFIX|CUSTOM}}"
|
|
13
|
+
},
|
|
14
|
+
"access": "{{ACCESS|public}}",
|
|
15
|
+
"create_access_controls": {{CREATE_ACCESS_CONTROLS|true}},
|
|
16
|
+
"live_feed_enabled": {{LIVE_FEED_ENABLED|false}},
|
|
17
|
+
"is_extendable": {{IS_EXTENDABLE|true}},
|
|
18
|
+
"create_module": {{CREATE_MODULE|true}},
|
|
19
|
+
"icon": "{{ICON|}}",
|
|
20
|
+
"user_role": "{{USER_ROLE|}}",
|
|
21
|
+
"fields": [
|
|
22
|
+
{
|
|
23
|
+
"column_name": "{{FIELD1_NAME|description}}",
|
|
24
|
+
"column_label": "{{FIELD1_LABEL|Description}}",
|
|
25
|
+
"type": "{{FIELD1_TYPE|string}}",
|
|
26
|
+
"max_length": {{FIELD1_LENGTH|255}},
|
|
27
|
+
"mandatory": {{FIELD1_MANDATORY|false}},
|
|
28
|
+
"display": {{FIELD1_DISPLAY|true}},
|
|
29
|
+
"active": true
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"acls": {
|
|
33
|
+
"create": "{{ACL_CREATE|true}}",
|
|
34
|
+
"read": "{{ACL_READ|true}}",
|
|
35
|
+
"write": "{{ACL_WRITE|true}}",
|
|
36
|
+
"delete": "{{ACL_DELETE|admin}}"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"variables": {
|
|
40
|
+
"TABLE_NAME": "u_custom_table",
|
|
41
|
+
"TABLE_DESCRIPTION": "A custom ServiceNow table",
|
|
42
|
+
"LABEL": "Custom Table",
|
|
43
|
+
"PLURAL": "Custom Tables",
|
|
44
|
+
"EXTENDS_TABLE": "task",
|
|
45
|
+
"PREFIX": "CUSTOM",
|
|
46
|
+
"ACCESS": "public",
|
|
47
|
+
"CREATE_ACCESS_CONTROLS": true,
|
|
48
|
+
"LIVE_FEED_ENABLED": false,
|
|
49
|
+
"IS_EXTENDABLE": true,
|
|
50
|
+
"CREATE_MODULE": true,
|
|
51
|
+
"ICON": "",
|
|
52
|
+
"USER_ROLE": "",
|
|
53
|
+
"FIELD1_NAME": "description",
|
|
54
|
+
"FIELD1_LABEL": "Description",
|
|
55
|
+
"FIELD1_TYPE": "string",
|
|
56
|
+
"FIELD1_LENGTH": 255,
|
|
57
|
+
"FIELD1_MANDATORY": false,
|
|
58
|
+
"FIELD1_DISPLAY": true,
|
|
59
|
+
"ACL_CREATE": "true",
|
|
60
|
+
"ACL_READ": "true",
|
|
61
|
+
"ACL_WRITE": "true",
|
|
62
|
+
"ACL_DELETE": "admin"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "widget",
|
|
3
|
+
"name": "{{WIDGET_NAME}}",
|
|
4
|
+
"description": "{{WIDGET_DESCRIPTION}}",
|
|
5
|
+
"config": {
|
|
6
|
+
"id": "{{WIDGET_ID}}",
|
|
7
|
+
"title": "{{WIDGET_TITLE}}",
|
|
8
|
+
"category": "{{CATEGORY|custom}}",
|
|
9
|
+
"template": "<div class=\"{{WIDGET_CLASS}}\">\n <!-- Widget HTML here -->\n</div>",
|
|
10
|
+
"css": ".{{WIDGET_CLASS}} {\n /* Widget styles here */\n}",
|
|
11
|
+
"client_script": "function() {\n var c = this;\n \n // Client controller logic here\n c.data = c.data || {};\n}",
|
|
12
|
+
"server_script": "(function() {\n // Server script logic here\n data = data || {};\n \n // Fetch data from ServiceNow\n \n})()",
|
|
13
|
+
"option_schema": "[]",
|
|
14
|
+
"demo_data": "{}",
|
|
15
|
+
"has_preview": true
|
|
16
|
+
},
|
|
17
|
+
"variables": {
|
|
18
|
+
"WIDGET_NAME": "My Widget",
|
|
19
|
+
"WIDGET_DESCRIPTION": "A custom ServiceNow widget",
|
|
20
|
+
"WIDGET_ID": "my_widget",
|
|
21
|
+
"WIDGET_TITLE": "My Widget",
|
|
22
|
+
"WIDGET_CLASS": "my-widget",
|
|
23
|
+
"CATEGORY": "custom"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "composite",
|
|
3
|
+
"name": "Incident Management System Template",
|
|
4
|
+
"description": "Complete incident management system with dashboard, workflows, and automation",
|
|
5
|
+
"category": "patterns/composite",
|
|
6
|
+
"artifacts": [
|
|
7
|
+
{
|
|
8
|
+
"type": "widget",
|
|
9
|
+
"template": "patterns/widget.dashboard",
|
|
10
|
+
"variables": {
|
|
11
|
+
"WIDGET_NAME": "incident_dashboard",
|
|
12
|
+
"WIDGET_TITLE": "Incident Management Dashboard",
|
|
13
|
+
"WIDGET_DESCRIPTION": "Real-time incident tracking and analytics",
|
|
14
|
+
"TABLE_NAME": "incident"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "widget",
|
|
19
|
+
"template": "patterns/widget.datatable",
|
|
20
|
+
"variables": {
|
|
21
|
+
"WIDGET_NAME": "incident_list",
|
|
22
|
+
"WIDGET_TITLE": "Active Incidents",
|
|
23
|
+
"WIDGET_DESCRIPTION": "Interactive list of active incidents",
|
|
24
|
+
"TABLE_NAME": "incident",
|
|
25
|
+
"ENABLE_INLINE_EDIT": "true"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"type": "flow",
|
|
30
|
+
"template": "patterns/flow.approval",
|
|
31
|
+
"variables": {
|
|
32
|
+
"FLOW_NAME": "incident_escalation",
|
|
33
|
+
"FLOW_DESCRIPTION": "Automatic incident escalation based on priority and age",
|
|
34
|
+
"TABLE_NAME": "incident",
|
|
35
|
+
"TRIGGER_TYPE": "scheduled",
|
|
36
|
+
"TRIGGER_CONDITION": "priority IN (1,2) AND state != 'resolved'"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"type": "business_rule",
|
|
41
|
+
"template": "base/business_rule",
|
|
42
|
+
"variables": {
|
|
43
|
+
"NAME": "incident_auto_assignment",
|
|
44
|
+
"DESCRIPTION": "Automatically assign incidents based on category",
|
|
45
|
+
"TABLE": "incident",
|
|
46
|
+
"WHEN": "before",
|
|
47
|
+
"CONDITION": "current.assigned_to.nil() && !current.category.nil()",
|
|
48
|
+
"SCRIPT": "// Auto-assignment logic\nvar category = current.getValue('category');\nvar assignmentGroup = '';\n\nswitch(category) {\n case 'hardware':\n assignmentGroup = 'hardware_support';\n break;\n case 'software':\n assignmentGroup = 'software_support';\n break;\n case 'network':\n assignmentGroup = 'network_support';\n break;\n default:\n assignmentGroup = 'service_desk';\n}\n\ncurrent.assignment_group = assignmentGroup;"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"type": "script_include",
|
|
53
|
+
"template": "base/script_include",
|
|
54
|
+
"variables": {
|
|
55
|
+
"CLASS_NAME": "IncidentAnalytics",
|
|
56
|
+
"DESCRIPTION": "Utility functions for incident analytics and reporting",
|
|
57
|
+
"SCRIPT": "var IncidentAnalytics = Class.create();\nIncidentAnalytics.prototype = {\n initialize: function() {},\n \n getMetrics: function() {\n var metrics = {};\n \n // Total incidents\n var gr = new GlideRecord('incident');\n gr.addActiveQuery();\n gr.query();\n metrics.total = gr.getRowCount();\n \n // By priority\n var priorities = {};\n gr = new GlideRecord('incident');\n gr.addActiveQuery();\n gr.query();\n while (gr.next()) {\n var priority = gr.getValue('priority') || 'undefined';\n priorities[priority] = (priorities[priority] || 0) + 1;\n }\n metrics.byPriority = priorities;\n \n // Average resolution time\n gr = new GlideRecord('incident');\n gr.addQuery('state', 'resolved');\n gr.orderByDesc('sys_updated_on');\n gr.setLimit(100);\n gr.query();\n \n var totalTime = 0;\n var count = 0;\n while (gr.next()) {\n var created = new GlideDateTime(gr.sys_created_on);\n var resolved = new GlideDateTime(gr.resolved_at);\n if (resolved.getNumericValue() > created.getNumericValue()) {\n totalTime += resolved.getNumericValue() - created.getNumericValue();\n count++;\n }\n }\n \n if (count > 0) {\n metrics.avgResolutionTime = Math.round(totalTime / count / 1000 / 60); // minutes\n }\n \n return metrics;\n },\n \n type: 'IncidentAnalytics'\n};"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"type": "table",
|
|
62
|
+
"template": "base/table",
|
|
63
|
+
"variables": {
|
|
64
|
+
"NAME": "u_incident_metrics",
|
|
65
|
+
"LABEL": "Incident Metrics",
|
|
66
|
+
"EXTENDS": "sys_metadata",
|
|
67
|
+
"FIELDS": [
|
|
68
|
+
{
|
|
69
|
+
"name": "metric_date",
|
|
70
|
+
"label": "Metric Date",
|
|
71
|
+
"type": "glide_date",
|
|
72
|
+
"mandatory": true
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"name": "total_incidents",
|
|
76
|
+
"label": "Total Incidents",
|
|
77
|
+
"type": "integer",
|
|
78
|
+
"default": "0"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"name": "high_priority",
|
|
82
|
+
"label": "High Priority",
|
|
83
|
+
"type": "integer",
|
|
84
|
+
"default": "0"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"name": "avg_resolution_time",
|
|
88
|
+
"label": "Avg Resolution Time (min)",
|
|
89
|
+
"type": "decimal",
|
|
90
|
+
"default": "0"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"name": "sla_breaches",
|
|
94
|
+
"label": "SLA Breaches",
|
|
95
|
+
"type": "integer",
|
|
96
|
+
"default": "0"
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
],
|
|
102
|
+
"dependencies": [
|
|
103
|
+
{
|
|
104
|
+
"from": "widget.incident_dashboard",
|
|
105
|
+
"to": "script_include.IncidentAnalytics",
|
|
106
|
+
"type": "uses"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"from": "flow.incident_escalation",
|
|
110
|
+
"to": "table.incident",
|
|
111
|
+
"type": "updates"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"from": "business_rule.incident_auto_assignment",
|
|
115
|
+
"to": "table.incident",
|
|
116
|
+
"type": "triggers_on"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"from": "script_include.IncidentAnalytics",
|
|
120
|
+
"to": "table.u_incident_metrics",
|
|
121
|
+
"type": "writes_to"
|
|
122
|
+
}
|
|
123
|
+
],
|
|
124
|
+
"deployment_order": [
|
|
125
|
+
"table.u_incident_metrics",
|
|
126
|
+
"script_include.IncidentAnalytics",
|
|
127
|
+
"business_rule.incident_auto_assignment",
|
|
128
|
+
"flow.incident_escalation",
|
|
129
|
+
"widget.incident_list",
|
|
130
|
+
"widget.incident_dashboard"
|
|
131
|
+
],
|
|
132
|
+
"variables": {
|
|
133
|
+
"SYSTEM_NAME": "Incident Management",
|
|
134
|
+
"SYSTEM_PREFIX": "inc_mgmt",
|
|
135
|
+
"PRIMARY_TABLE": "incident",
|
|
136
|
+
"NOTIFICATION_GROUP": "incident_managers",
|
|
137
|
+
"SLA_WARNING_THRESHOLD": "80",
|
|
138
|
+
"ESCALATION_TIMEOUT": "3600"
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "widget",
|
|
3
|
+
"name": "Dashboard Widget Template",
|
|
4
|
+
"description": "Template for creating dashboard widgets with charts and metrics",
|
|
5
|
+
"category": "patterns/dashboard",
|
|
6
|
+
"config": {
|
|
7
|
+
"name": "{{WIDGET_NAME|custom_dashboard}}",
|
|
8
|
+
"id": "{{WIDGET_ID|custom_dashboard}}",
|
|
9
|
+
"instance_id": "{{INSTANCE_ID|dashboard_}}",
|
|
10
|
+
"data": {
|
|
11
|
+
"title": "{{WIDGET_TITLE|Dashboard}}",
|
|
12
|
+
"short_description": "{{WIDGET_DESCRIPTION|Real-time dashboard with key metrics}}",
|
|
13
|
+
"roles": "{{WIDGET_ROLES|}}"
|
|
14
|
+
},
|
|
15
|
+
"options": [
|
|
16
|
+
{
|
|
17
|
+
"name": "refresh_interval",
|
|
18
|
+
"section": "Behavior",
|
|
19
|
+
"label": "Refresh Interval (seconds)",
|
|
20
|
+
"type": "integer",
|
|
21
|
+
"value": "30",
|
|
22
|
+
"help": "How often to refresh the dashboard data"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "color_scheme",
|
|
26
|
+
"section": "Appearance",
|
|
27
|
+
"label": "Color Scheme",
|
|
28
|
+
"type": "choice",
|
|
29
|
+
"value": "default",
|
|
30
|
+
"choices": [
|
|
31
|
+
{"label": "Default", "value": "default"},
|
|
32
|
+
{"label": "Dark", "value": "dark"},
|
|
33
|
+
{"label": "High Contrast", "value": "high-contrast"}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "chart_type",
|
|
38
|
+
"section": "Appearance",
|
|
39
|
+
"label": "Default Chart Type",
|
|
40
|
+
"type": "choice",
|
|
41
|
+
"value": "bar",
|
|
42
|
+
"choices": [
|
|
43
|
+
{"label": "Bar Chart", "value": "bar"},
|
|
44
|
+
{"label": "Line Chart", "value": "line"},
|
|
45
|
+
{"label": "Pie Chart", "value": "pie"},
|
|
46
|
+
{"label": "Donut Chart", "value": "donut"}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"html": [
|
|
51
|
+
"<div class=\"dashboard-widget\" ng-class=\"{'dark-theme': options.color_scheme === 'dark', 'high-contrast': options.color_scheme === 'high-contrast'}\">",
|
|
52
|
+
" <div class=\"dashboard-header\">",
|
|
53
|
+
" <h2 class=\"dashboard-title\">{{data.title}}</h2>",
|
|
54
|
+
" <div class=\"dashboard-controls\">",
|
|
55
|
+
" <button class=\"btn btn-sm\" ng-click=\"c.refresh()\" title=\"Refresh\">",
|
|
56
|
+
" <i class=\"fa fa-refresh\" ng-class=\"{'fa-spin': c.loading}\"></i>",
|
|
57
|
+
" </button>",
|
|
58
|
+
" <button class=\"btn btn-sm\" ng-click=\"c.toggleFullscreen()\" title=\"Fullscreen\">",
|
|
59
|
+
" <i class=\"fa\" ng-class=\"c.fullscreen ? 'fa-compress' : 'fa-expand'\"></i>",
|
|
60
|
+
" </button>",
|
|
61
|
+
" </div>",
|
|
62
|
+
" </div>",
|
|
63
|
+
" ",
|
|
64
|
+
" <div class=\"dashboard-metrics\" ng-if=\"!c.loading\">",
|
|
65
|
+
" <div class=\"metric-card\" ng-repeat=\"metric in c.metrics\">",
|
|
66
|
+
" <div class=\"metric-value\" ng-style=\"{'color': metric.color}\">{{metric.value}}</div>",
|
|
67
|
+
" <div class=\"metric-label\">{{metric.label}}</div>",
|
|
68
|
+
" <div class=\"metric-trend\" ng-if=\"metric.trend\">",
|
|
69
|
+
" <i class=\"fa\" ng-class=\"metric.trend > 0 ? 'fa-arrow-up text-success' : 'fa-arrow-down text-danger'\"></i>",
|
|
70
|
+
" <span>{{metric.trend}}%</span>",
|
|
71
|
+
" </div>",
|
|
72
|
+
" </div>",
|
|
73
|
+
" </div>",
|
|
74
|
+
" ",
|
|
75
|
+
" <div class=\"dashboard-charts\" ng-if=\"!c.loading\">",
|
|
76
|
+
" <div class=\"chart-container\" ng-repeat=\"chart in c.charts\">",
|
|
77
|
+
" <h3>{{chart.title}}</h3>",
|
|
78
|
+
" <canvas id=\"chart-{{$index}}\" width=\"400\" height=\"200\"></canvas>",
|
|
79
|
+
" </div>",
|
|
80
|
+
" </div>",
|
|
81
|
+
" ",
|
|
82
|
+
" <div class=\"dashboard-loading\" ng-if=\"c.loading\">",
|
|
83
|
+
" <i class=\"fa fa-spinner fa-spin fa-3x\"></i>",
|
|
84
|
+
" <p>Loading dashboard data...</p>",
|
|
85
|
+
" </div>",
|
|
86
|
+
"</div>"
|
|
87
|
+
],
|
|
88
|
+
"css": [
|
|
89
|
+
".dashboard-widget {",
|
|
90
|
+
" padding: 20px;",
|
|
91
|
+
" background: #fff;",
|
|
92
|
+
" border-radius: 8px;",
|
|
93
|
+
" box-shadow: 0 2px 4px rgba(0,0,0,0.1);",
|
|
94
|
+
"}",
|
|
95
|
+
"",
|
|
96
|
+
".dashboard-widget.dark-theme {",
|
|
97
|
+
" background: #1a1a1a;",
|
|
98
|
+
" color: #fff;",
|
|
99
|
+
"}",
|
|
100
|
+
"",
|
|
101
|
+
".dashboard-widget.high-contrast {",
|
|
102
|
+
" border: 2px solid #000;",
|
|
103
|
+
"}",
|
|
104
|
+
"",
|
|
105
|
+
".dashboard-header {",
|
|
106
|
+
" display: flex;",
|
|
107
|
+
" justify-content: space-between;",
|
|
108
|
+
" align-items: center;",
|
|
109
|
+
" margin-bottom: 20px;",
|
|
110
|
+
"}",
|
|
111
|
+
"",
|
|
112
|
+
".dashboard-title {",
|
|
113
|
+
" margin: 0;",
|
|
114
|
+
" font-size: 24px;",
|
|
115
|
+
" font-weight: 600;",
|
|
116
|
+
"}",
|
|
117
|
+
"",
|
|
118
|
+
".dashboard-controls button {",
|
|
119
|
+
" margin-left: 10px;",
|
|
120
|
+
"}",
|
|
121
|
+
"",
|
|
122
|
+
".dashboard-metrics {",
|
|
123
|
+
" display: grid;",
|
|
124
|
+
" grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));",
|
|
125
|
+
" gap: 20px;",
|
|
126
|
+
" margin-bottom: 30px;",
|
|
127
|
+
"}",
|
|
128
|
+
"",
|
|
129
|
+
".metric-card {",
|
|
130
|
+
" background: #f5f5f5;",
|
|
131
|
+
" padding: 20px;",
|
|
132
|
+
" border-radius: 8px;",
|
|
133
|
+
" text-align: center;",
|
|
134
|
+
" transition: transform 0.2s;",
|
|
135
|
+
"}",
|
|
136
|
+
"",
|
|
137
|
+
".dark-theme .metric-card {",
|
|
138
|
+
" background: #2a2a2a;",
|
|
139
|
+
"}",
|
|
140
|
+
"",
|
|
141
|
+
".metric-card:hover {",
|
|
142
|
+
" transform: translateY(-2px);",
|
|
143
|
+
" box-shadow: 0 4px 8px rgba(0,0,0,0.1);",
|
|
144
|
+
"}",
|
|
145
|
+
"",
|
|
146
|
+
".metric-value {",
|
|
147
|
+
" font-size: 36px;",
|
|
148
|
+
" font-weight: bold;",
|
|
149
|
+
" margin-bottom: 5px;",
|
|
150
|
+
"}",
|
|
151
|
+
"",
|
|
152
|
+
".metric-label {",
|
|
153
|
+
" font-size: 14px;",
|
|
154
|
+
" color: #666;",
|
|
155
|
+
" text-transform: uppercase;",
|
|
156
|
+
"}",
|
|
157
|
+
"",
|
|
158
|
+
".dark-theme .metric-label {",
|
|
159
|
+
" color: #999;",
|
|
160
|
+
"}",
|
|
161
|
+
"",
|
|
162
|
+
".metric-trend {",
|
|
163
|
+
" margin-top: 10px;",
|
|
164
|
+
" font-size: 14px;",
|
|
165
|
+
"}",
|
|
166
|
+
"",
|
|
167
|
+
".dashboard-charts {",
|
|
168
|
+
" display: grid;",
|
|
169
|
+
" grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));",
|
|
170
|
+
" gap: 30px;",
|
|
171
|
+
"}",
|
|
172
|
+
"",
|
|
173
|
+
".chart-container {",
|
|
174
|
+
" background: #f9f9f9;",
|
|
175
|
+
" padding: 20px;",
|
|
176
|
+
" border-radius: 8px;",
|
|
177
|
+
"}",
|
|
178
|
+
"",
|
|
179
|
+
".dark-theme .chart-container {",
|
|
180
|
+
" background: #2a2a2a;",
|
|
181
|
+
"}",
|
|
182
|
+
"",
|
|
183
|
+
".dashboard-loading {",
|
|
184
|
+
" text-align: center;",
|
|
185
|
+
" padding: 60px 20px;",
|
|
186
|
+
" color: #666;",
|
|
187
|
+
"}",
|
|
188
|
+
"",
|
|
189
|
+
".dark-theme .dashboard-loading {",
|
|
190
|
+
" color: #999;",
|
|
191
|
+
"}",
|
|
192
|
+
"",
|
|
193
|
+
"@media (max-width: 768px) {",
|
|
194
|
+
" .dashboard-metrics {",
|
|
195
|
+
" grid-template-columns: 1fr;",
|
|
196
|
+
" }",
|
|
197
|
+
" .dashboard-charts {",
|
|
198
|
+
" grid-template-columns: 1fr;",
|
|
199
|
+
" }",
|
|
200
|
+
"}"
|
|
201
|
+
],
|
|
202
|
+
"client_controller": "{{CLIENT_CONTROLLER|dashboard_controller}}",
|
|
203
|
+
"script": "{{SERVER_SCRIPT|dashboard_server_script}}",
|
|
204
|
+
"link_function": "{{LINK_FUNCTION|}}",
|
|
205
|
+
"demo_data": {
|
|
206
|
+
"metrics": [
|
|
207
|
+
{"label": "Total Items", "value": "1,234", "color": "#007bff", "trend": 12},
|
|
208
|
+
{"label": "Active Users", "value": "456", "color": "#28a745", "trend": 5},
|
|
209
|
+
{"label": "Pending Tasks", "value": "78", "color": "#ffc107", "trend": -3},
|
|
210
|
+
{"label": "Completed", "value": "89%", "color": "#17a2b8", "trend": 2}
|
|
211
|
+
],
|
|
212
|
+
"charts": [
|
|
213
|
+
{
|
|
214
|
+
"title": "Weekly Trend",
|
|
215
|
+
"type": "line",
|
|
216
|
+
"data": {
|
|
217
|
+
"labels": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
|
218
|
+
"datasets": [{
|
|
219
|
+
"label": "Items",
|
|
220
|
+
"data": [65, 59, 80, 81, 56, 55, 40]
|
|
221
|
+
}]
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
]
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
"variables": {
|
|
228
|
+
"WIDGET_NAME": "custom_dashboard",
|
|
229
|
+
"WIDGET_ID": "custom_dashboard",
|
|
230
|
+
"INSTANCE_ID": "dashboard_",
|
|
231
|
+
"WIDGET_TITLE": "Dashboard",
|
|
232
|
+
"WIDGET_DESCRIPTION": "Real-time dashboard with key metrics",
|
|
233
|
+
"WIDGET_ROLES": "",
|
|
234
|
+
"CLIENT_CONTROLLER": "function($scope, $http, $timeout) {\n var c = this;\n \n c.loading = true;\n c.fullscreen = false;\n c.metrics = [];\n c.charts = [];\n \n c.refresh = function() {\n c.loading = true;\n c.server.get({\n action: 'get_dashboard_data'\n }).then(function(response) {\n c.metrics = response.data.metrics || [];\n c.charts = response.data.charts || [];\n c.loading = false;\n \n // Render charts\n $timeout(function() {\n c.renderCharts();\n }, 100);\n });\n };\n \n c.renderCharts = function() {\n c.charts.forEach(function(chart, index) {\n var ctx = document.getElementById('chart-' + index);\n if (ctx) {\n new Chart(ctx.getContext('2d'), {\n type: c.options.chart_type || chart.type || 'bar',\n data: chart.data,\n options: {\n responsive: true,\n maintainAspectRatio: false\n }\n });\n }\n });\n };\n \n c.toggleFullscreen = function() {\n c.fullscreen = !c.fullscreen;\n // Implement fullscreen logic\n };\n \n // Initial load\n c.refresh();\n \n // Auto-refresh\n if (c.options.refresh_interval > 0) {\n var refreshTimer = $timeout(function refresh() {\n c.refresh();\n refreshTimer = $timeout(refresh, c.options.refresh_interval * 1000);\n }, c.options.refresh_interval * 1000);\n \n $scope.$on('$destroy', function() {\n $timeout.cancel(refreshTimer);\n });\n }\n}",
|
|
235
|
+
"SERVER_SCRIPT": "(function() {\n try {\n data.metrics = [];\n data.charts = [];\n gs.log('Dashboard widget server script started', 'dashboard_widget');\n \n if (input && input.action === 'get_dashboard_data') {\n // Example: Fetch incident metrics\n var gr = new GlideRecord('incident');\n gr.addQuery('active', 'true'); // ✅ FIXED: Use string instead of boolean\n gr.query();\n \n var totalCount = gr.getRowCount();\n gs.log('Found ' + totalCount + ' active incidents', 'dashboard_widget');\n \n // Get priority breakdown\n var priorities = {};\n gr = new GlideRecord('incident');\n gr.addQuery('active', 'true'); // ✅ FIXED: Use string instead of boolean\n gr.query();\n \n while (gr.next()) {\n var priority = gr.getValue('priority') || 'undefined';\n priorities[priority] = (priorities[priority] || 0) + 1;\n }\n \n // Build metrics\n data.metrics = [\n {\n label: 'Total Incidents',\n value: totalCount.toString(),\n color: '#007bff',\n trend: 5\n },\n {\n label: 'High Priority',\n value: (priorities['1'] || 0).toString(),\n color: '#dc3545',\n trend: -2\n },\n {\n label: 'Medium Priority',\n value: (priorities['2'] || 0).toString(),\n color: '#ffc107',\n trend: 3\n },\n {\n label: 'Low Priority',\n value: (priorities['3'] || 0).toString(),\n color: '#28a745',\n trend: 1\n }\n ];\n \n // Build chart data\n data.charts = [\n {\n title: 'Incidents by Priority',\n type: 'bar',\n data: {\n labels: ['High', 'Medium', 'Low'],\n datasets: [{\n label: 'Incidents',\n data: [\n priorities['1'] || 0,\n priorities['2'] || 0,\n priorities['3'] || 0\n ],\n backgroundColor: ['#dc3545', '#ffc107', '#28a745']\n }]\n }\n }\n ];\n \n gs.log('Dashboard data prepared successfully', 'dashboard_widget');\n }\n } catch (error) {\n gs.error('Dashboard widget error: ' + error.message, 'dashboard_widget');\n data.error = 'Error loading dashboard: ' + error.message;\n data.success = false;\n }\n})()",
|
|
236
|
+
"LINK_FUNCTION": ""
|
|
237
|
+
}
|
|
238
|
+
}
|