|
41384
|
877
|
57
|
2026-04-17T06:12:24.445542+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-17/1776 /Users/lukas/.screenpipe/data/data/2026-04-17/1776406344445_m1.jpg...
|
Firefox
|
Amazon Web Services Switch Role — Work
|
1
|
signin.aws.amazon.com/switchrole?roleName=Producti signin.aws.amazon.com/switchrole?roleName=Production_View_Only&account=jiminny...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
New Tab
New Tab
New Tab
New Tab
CloudWatch | us-east-2
CloudWatch | us-east-2
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Amazon Web Services Switch Role
Amazon Web Services Switch Role
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Language English
English
Switch Role
Switch Role
Switching roles enables you to manage resources across Amazon Web Services accounts using a single user. When you switch roles, you temporarily take on the permissions assigned to the new role. When you exit the role, you give up those permissions and get your original permissions back.
Learn more Learn more
Learn more
Account ID
The 12-digit account number or the alias of the account in which the role exists.
jiminny
IAM role name
The name of the role that you want to assume which can be found at the end of the role's ARN. For example, provide the
TestRole
role name from the following role ARN: arn:aws:iam::123456789012:role/
TestRole
.
Production_View_Only
Display name -
optional
This name will appear in the console navigation bar when active. Choose a name to help identify the permission set assigned to the role.
Display name - optional
Display color -
optional
The selected color displays in the console navigation when this role is active
Display color - optional dropdown None
None
Cancel
Cancel
Switch Role
©
2026
,
Amazon Web Services, Inc. or its affiliates.
Privacy
Privacy
Terms
Terms...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Amazon Web Services Switch Role","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Amazon Web Services Switch Role","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Language English","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"English","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Switch Role","depth":12,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Switch Role","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Switching roles enables you to manage resources across Amazon Web Services accounts using a single user. When you switch roles, you temporarily take on the permissions assigned to the new role. When you exit the role, you give up those permissions and get your original permissions back.","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more Learn more","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Account ID","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The 12-digit account number or the alias of the account in which the role exists.","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"jiminny","depth":11,"value":"jiminny","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"IAM role name","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The name of the role that you want to assume which can be found at the end of the role's ARN. For example, provide the","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TestRole","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"role name from the following role ARN: arn:aws:iam::123456789012:role/","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TestRole","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Production_View_Only","depth":11,"value":"Production_View_Only","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Display name -","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"optional","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This name will appear in the console navigation bar when active. Choose a name to help identify the permission set assigned to the role.","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Display name - optional","depth":11,"placeholder":"Production_View_Only @ jiminny","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Display color -","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"optional","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The selected color displays in the console navigation when this role is active","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Display color - optional dropdown None","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"None","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Cancel","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Cancel","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Switch Role","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"©","depth":14,"bounds":{"left":1.0,"top":0.0,"width":-0.074305534,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":14,"bounds":{"left":1.0,"top":0.0,"width":-0.08263886,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Amazon Web Services, Inc. or its affiliates.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Privacy","depth":15,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Privacy","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Terms","depth":15,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Terms","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
6843880781007776053
|
9092882419092502230
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
New Tab
New Tab
New Tab
New Tab
CloudWatch | us-east-2
CloudWatch | us-east-2
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Amazon Web Services Switch Role
Amazon Web Services Switch Role
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Language English
English
Switch Role
Switch Role
Switching roles enables you to manage resources across Amazon Web Services accounts using a single user. When you switch roles, you temporarily take on the permissions assigned to the new role. When you exit the role, you give up those permissions and get your original permissions back.
Learn more Learn more
Learn more
Account ID
The 12-digit account number or the alias of the account in which the role exists.
jiminny
IAM role name
The name of the role that you want to assume which can be found at the end of the role's ARN. For example, provide the
TestRole
role name from the following role ARN: arn:aws:iam::123456789012:role/
TestRole
.
Production_View_Only
Display name -
optional
This name will appear in the console navigation bar when active. Choose a name to help identify the permission set assigned to the role.
Display name - optional
Display color -
optional
The selected color displays in the console navigation when this role is active
Display color - optional dropdown None
None
Cancel
Cancel
Switch Role
©
2026
,
Amazon Web Services, Inc. or its affiliates.
Privacy
Privacy
Terms
Terms...
|
NULL
|
|
41385
|
878
|
82
|
2026-04-17T06:12:24.465253+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-17/1776 /Users/lukas/.screenpipe/data/data/2026-04-17/1776406344465_m2.jpg...
|
Firefox
|
Amazon Web Services Switch Role — Work
|
1
|
signin.aws.amazon.com/switchrole?roleName=Producti signin.aws.amazon.com/switchrole?roleName=Production_View_Only&account=jiminny...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
New Tab
New Tab
New Tab
New Tab
CloudWatch | us-east-2
CloudWatch | us-east-2
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Amazon Web Services Switch Role
Amazon Web Services Switch Role
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Language English
English
Switch Role
Switch Role
Switching roles enables you to manage resources across Amazon Web Services accounts using a single user. When you switch roles, you temporarily take on the permissions assigned to the new role. When you exit the role, you give up those permissions and get your original permissions back.
Learn more Learn more
Learn more
Account ID
The 12-digit account number or the alias of the account in which the role exists.
jiminny
IAM role name
The name of the role that you want to assume which can be found at the end of the role's ARN. For example, provide the
TestRole
role name from the following role ARN: arn:aws:iam::123456789012:role/
TestRole
.
Production_View_Only
Display name -
optional
This name will appear in the console navigation bar when active. Choose a name to help identify the permission set assigned to the role.
Display name - optional
Display color -
optional
The selected color displays in the console navigation when this role is active
Display color - optional dropdown None
None
Cancel
Cancel
Switch Role
©
2026
,
Amazon Web Services, Inc. or its affiliates.
Privacy
Privacy
Terms
Terms...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.045138888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.05486111,"width":0.11875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"bounds":{"left":0.0,"top":0.07361111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"bounds":{"left":0.015625,"top":0.083333336,"width":0.11171875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.10208333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.015625,"top":0.11180556,"width":0.017578125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":4,"bounds":{"left":0.0,"top":0.13055556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":5,"bounds":{"left":0.015625,"top":0.14027777,"width":0.53398436,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.15902779,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.015625,"top":0.16875,"width":0.017578125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.1875,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.015625,"top":0.19722222,"width":0.017578125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.21597221,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.22569445,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.24444444,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.25416666,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Amazon Web Services Switch Role","depth":4,"bounds":{"left":0.0,"top":0.27291667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Amazon Web Services Switch Role","depth":5,"bounds":{"left":0.015625,"top":0.28263888,"width":0.07070313,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.27916667,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.30277777,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Language English","depth":13,"bounds":{"left":0.9574219,"top":0.048611112,"width":0.0425781,"height":0.020833334},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"English","depth":14,"bounds":{"left":0.9652344,"top":0.05277778,"width":0.01953125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Switch Role","depth":12,"bounds":{"left":0.39882812,"top":0.09791667,"width":0.03828125,"height":0.015972223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Switch Role","depth":13,"bounds":{"left":0.39882812,"top":0.09791667,"width":0.03828125,"height":0.015972223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Switching roles enables you to manage resources across Amazon Web Services accounts using a single user. When you switch roles, you temporarily take on the permissions assigned to the new role. When you exit the role, you give up those permissions and get your original permissions back.","depth":12,"bounds":{"left":0.39882812,"top":0.11666667,"width":0.29179686,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more Learn more","depth":12,"bounds":{"left":0.43710938,"top":0.1388889,"width":0.0328125,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":13,"bounds":{"left":0.43710938,"top":0.1388889,"width":0.025390625,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Account ID","depth":13,"bounds":{"left":0.39882812,"top":0.17638889,"width":0.0265625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The 12-digit account number or the alias of the account in which the role exists.","depth":12,"bounds":{"left":0.39882812,"top":0.19097222,"width":0.16914062,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"jiminny","depth":11,"bounds":{"left":0.39882812,"top":0.20416667,"width":0.296875,"height":0.022222223},"value":"jiminny","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"IAM role name","depth":13,"bounds":{"left":0.39882812,"top":0.24166666,"width":0.0359375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The name of the role that you want to assume which can be found at the end of the role's ARN. For example, provide the","depth":12,"bounds":{"left":0.39882812,"top":0.25625,"width":0.2566406,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TestRole","depth":12,"bounds":{"left":0.65546876,"top":0.25625,"width":0.01875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"role name from the following role ARN: arn:aws:iam::123456789012:role/","depth":12,"bounds":{"left":0.39882812,"top":0.25625,"width":0.28515625,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TestRole","depth":12,"bounds":{"left":0.54609376,"top":0.2673611,"width":0.01875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":12,"bounds":{"left":0.5648438,"top":0.2673611,"width":0.001171875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Production_View_Only","depth":11,"bounds":{"left":0.39882812,"top":0.28055555,"width":0.296875,"height":0.022222223},"value":"Production_View_Only","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Display name -","depth":13,"bounds":{"left":0.39882812,"top":0.31805557,"width":0.037890624,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"optional","depth":13,"bounds":{"left":0.43671876,"top":0.31805557,"width":0.0203125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This name will appear in the console navigation bar when active. Choose a name to help identify the permission set assigned to the role.","depth":12,"bounds":{"left":0.39882812,"top":0.3326389,"width":0.28867188,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Display name - optional","depth":11,"bounds":{"left":0.39882812,"top":0.34583333,"width":0.296875,"height":0.022222223},"placeholder":"Production_View_Only @ jiminny","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Display color -","depth":13,"bounds":{"left":0.39882812,"top":0.38333333,"width":0.03671875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"optional","depth":13,"bounds":{"left":0.43554688,"top":0.38333333,"width":0.019921875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The selected color displays in the console navigation when this role is active","depth":12,"bounds":{"left":0.39882812,"top":0.39791667,"width":0.16054687,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Display color - optional dropdown None","depth":12,"bounds":{"left":0.39882812,"top":0.41111112,"width":0.296875,"height":0.022222223},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"None","depth":15,"bounds":{"left":0.41171876,"top":0.41597223,"width":0.012890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Cancel","depth":11,"bounds":{"left":0.6140625,"top":0.4611111,"width":0.033984374,"height":0.022222223},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Cancel","depth":12,"bounds":{"left":0.62226564,"top":0.46597221,"width":0.017578125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Switch Role","depth":11,"bounds":{"left":0.65585935,"top":0.4611111,"width":0.04765625,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"©","depth":14,"bounds":{"left":0.8375,"top":0.98541665,"width":0.0046875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":14,"bounds":{"left":0.8421875,"top":0.98541665,"width":0.0109375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.853125,"top":0.98541665,"width":0.002734375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Amazon Web Services, Inc. or its affiliates.","depth":14,"bounds":{"left":0.8558594,"top":0.98541665,"width":0.08867188,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Privacy","depth":15,"bounds":{"left":0.95625,"top":0.98541665,"width":0.015234375,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Privacy","depth":16,"bounds":{"left":0.95625,"top":0.98541665,"width":0.015234375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Terms","depth":15,"bounds":{"left":0.98125,"top":0.98541665,"width":0.012890625,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Terms","depth":16,"bounds":{"left":0.98125,"top":0.98541665,"width":0.012890625,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
6843880781007776053
|
9092882419092502230
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
New Tab
New Tab
New Tab
New Tab
CloudWatch | us-east-2
CloudWatch | us-east-2
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Amazon Web Services Switch Role
Amazon Web Services Switch Role
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Language English
English
Switch Role
Switch Role
Switching roles enables you to manage resources across Amazon Web Services accounts using a single user. When you switch roles, you temporarily take on the permissions assigned to the new role. When you exit the role, you give up those permissions and get your original permissions back.
Learn more Learn more
Learn more
Account ID
The 12-digit account number or the alias of the account in which the role exists.
jiminny
IAM role name
The name of the role that you want to assume which can be found at the end of the role's ARN. For example, provide the
TestRole
role name from the following role ARN: arn:aws:iam::123456789012:role/
TestRole
.
Production_View_Only
Display name -
optional
This name will appear in the console navigation bar when active. Choose a name to help identify the permission set assigned to the role.
Display name - optional
Display color -
optional
The selected color displays in the console navigation when this role is active
Display color - optional dropdown None
None
Cancel
Cancel
Switch Role
©
2026
,
Amazon Web Services, Inc. or its affiliates.
Privacy
Privacy
Terms
Terms...
|
41383
|
|
71970
|
1738
|
10
|
2026-04-22T14:35:50.708491+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-22/1776 /Users/lukas/.screenpipe/data/data/2026-04-22/1776868550708_m1.jpg...
|
Firefox
|
Jiminny MCP Connector - Product - Confluence — Wor Jiminny MCP Connector - Product - Confluence — Work...
|
1
|
jiminny.atlassian.net/wiki/spaces/PROD/pages/37282 jiminny.atlassian.net/wiki/spaces/PROD/pages/3728244737/Jiminny+MCP+Connector...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
[JY-20372] AI Reports > Empty page design and promotion - Jira
[JY-20372] AI Reports > Empty page design and promotion - Jira
Jiminny MCP Connector - Product - Confluence
Jiminny MCP Connector - Product - Confluence
Jiminny
Jiminny
Workers | Datadog
Workers | Datadog
Pull requests · jiminny/app
Pull requests · jiminny/app
[JY-20728] [HubSpot] Find the root cause of 429 hit and tweak API client rate limiter - Jira
[JY-20728] [HubSpot] Find the root cause of 429 hit and tweak API client rate limiter - Jira
JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app
JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app
Jiminny
Jiminny
CloudWatch | us-east-2
CloudWatch | us-east-2
Your 'Not enpough activities' report wasn't generated - [EMAIL] - Jiminny Mail
Your 'Not enpough activities' report wasn't generated - [EMAIL] - Jiminny Mail
Jiminny MCP Connector - Product - Confluence
Jiminny MCP Connector - Product - Confluence
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said what is the oauth required for mcp for clauide code and claude chat
You said
what is the oauth required for mcp for clauide code and claude chat
Listen
Show more options
Show thinking
Gemini said
Gemini said
To understand the OAuth requirements for the Model Context Protocol (MCP) in Claude Code and Claude Chat, it helps to look at how MCP handles secure connections.
MCP acts as a universal "USB port" that allows AI models to connect to external data sources and tools.
When connecting to remote, HTTP-based MCP servers, Anthropic relies on the
OAuth 2.1
authorization framework.
This ensures that Claude can access your protected tools securely using temporary tokens, rather than requiring you to copy and paste long-lived API keys, passwords, or configuration secrets.
View source details for citations from Stytch, Model Context Protocol, and Zuplo. Opens side panel.
+2
Here is exactly what is required and how OAuth is handled across both environments.
The Underlying OAuth Flow for MCP
The Underlying OAuth Flow for MCP
Whether you are using Claude Code or Claude Chat, the underlying architecture is identical.
The Claude application acts as the
OAuth Client
, and the remote tool you are connecting to acts as the
Resource Server
.
View source details for citation from Model Context Protocol. Opens side panel.
To build or connect to an MCP server, the OAuth integration must support this standard discovery and token exchange flow:
Initial Handshake (Discovery):
Claude attempts to connect to the MCP server without credentials. The server must reject this with a
401 Unauthorized
HTTP status and include a
WWW-Authenticate
header pointing to a Protected Resource Metadata (PRM) document.
Metadata Fetch:
Claude reads the PRM document to locate your specific Authorization Server (e.g., Okta, Auth0, Clerk, or a custom auth server).
View source details for citation from Model Context Protocol. Opens side panel.
User Consent:
Claude prompts the user to authenticate.
The user is temporarily redirected to a browser window to log in and explicitly grant permission (e.g., "Allow Claude to access your GitHub repositories").
View source details for citations from GitHub and Model Context Protocol. Opens side panel.
+1
Token Exchange:
Claude receives a temporary authorization code via a redirect, which it silently exchanges for a long-lived access token.
View source details for citation from Upstash. Opens side panel.
Access Granted:
Claude now includes this token in the header of subsequent requests to invoke tools and read data on your behalf.
View source details for citation from Model Context Protocol. Opens side panel.
MCP OAuth in Claude Code
MCP OAuth in Claude Code
Claude Code is Anthropic's command-line interface (CLI) tool for software engineering. When you connect Claude Code to a protected remote MCP server, the OAuth flow is adapted for the terminal:
Browser Handoff:
When Claude Code hits an MCP server that requires OAuth, it will generate a secure authorization link and automatically open your default desktop web browser (or output the URL to the terminal for headless environments).
Authentication:
Once you log in and approve access in the browser, the authorization server redirects the payload back to a local loopback port managed by Claude Code, handing off the authorization code.
View source details for citation from Model Context Protocol. Opens side panel.
Alternative (Static Headers):
If setting up a full OAuth 2.1 server is too complex for a quick internal tool, Claude Code also allows you to bypass the browser flow by injecting static bearer tokens directly via the CLI.
You can do this using the
--header
flag (e.g.,
claude mcp add my-server --transport http --header "Authorization: Bearer your-token"
).
View source details for citation from TrueFoundry. Opens side panel.
MCP OAuth in Claude Chat (Claude Desktop & Web)
MCP OAuth in Claude Chat (Claude Desktop & Web)
"Claude Chat" encompasses the visual interfaces—both the Claude Desktop application and the Claude.ai web platform.
Claude.ai (Web Custom Connectors):
When you add a remote MCP server via the "Custom Connectors" menu in your settings, Claude.ai handles the OAuth flow entirely in the browser. You simply paste the MCP server URL. Claude automatically parses the 401 discovery response and redirects you to the third-party service to grant permission, before seamlessly dropping you back into your chat session.
Claude Desktop:
Claude Desktop traditionally relies on a local configuration file (
claude_desktop_config.json
). While local stdio servers often require pasting API keys into this file, remote HTTP MCP servers utilizing OAuth eliminate this security risk.
When Claude Desktop encounters an OAuth-protected server, it pops open your system's default browser to capture your consent.
It then stores the resulting token securely in your operating system's native keychain or credential manager, keeping your
config.json
free of sensitive plaintext passwords.
View source details for citation from GitHub. Opens side panel.
The Bottom Line:
You do not need to build a bespoke authentication protocol for MCP.
If your external tool already utilizes standard OpenID Connect or OAuth 2.0/2.1, Claude Code and Claude Chat are heavily standardized to automatically discover those endpoints, route the user for consent, and manage the resulting tokens behind the scenes.
View source details for citation from GitHub. Opens side panel.
Sources
Sources
Enter a prompt for Gemini
encrypted
Enter a prompt for Gemini
encrypted
Open upload file menu
Tools
Open mode picker
Pro
Microphone
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Collapse sidebar Ctrl [
Collapse sidebar
Ctrl
[
Switch sites or apps
Switch sites or apps
Confluence
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Spaces
Spaces
Apps
Apps
Product
Product
More actions
More actions
Back to top
Back to top
Content
Content
Create Create
Create
Change view
Change view
Search by title
Results will update as you type.
Product Strategy 2025+ Change emoji
Product Strategy 2025+
Product Strategy 2025+
Competitive analysis Change emoji
Competitive analysis
Competitive analysis
Ways of working - Product processes Change emoji
Ways of working - Product processes
Ways of working - Product processes
Core Product Performance Metrics 📈
Core Product Performance Metrics
📈
Core Product Performance Metrics
Product Documentation Change emoji
Product Documentation
Product Documentation
Product Briefs Change emoji
Product Briefs
Product Briefs
Change emoji Activity Export
Activity Export
Change emoji Autologging activities
Autologging activities
Deal Insights - Multiple currencies
Deal Insights - Multiple currencies
Reinvent Themes & Topics (and ACS)
Reinvent Themes & Topics (and ACS)
Change emoji Billing Portal
Billing Portal
Change emoji Upload Video/Audio Recordings
Upload Video/Audio Recordings
White-Label Jiminny Instance
White-Label Jiminny Instance
Win/Loss Analysis for a Deal
Win/Loss Analysis for a Deal
Change emoji Hubspot app
Hubspot app
Change emoji Automatically hard delete data for churned customers
Automatically hard delete data for churned customers
Change emoji Ask Jiminny Anything on Call level
Ask Jiminny Anything on Call level
Change emoji Ask Jiminny for Open and Closed Deals
Ask Jiminny for Open and Closed Deals
Change emoji Ask Jiminny Anything on Deal level
Ask Jiminny Anything on Deal level
Change emoji Automatically record all calendar meetings
Automatically record all calendar meetings
Change emoji Product Tiering
Product Tiering
Change emoji Recording Consent
Recording Consent
Change emoji Automated CRM Filling
Automated CRM Filling
Change emoji Automated Exec Reports
Automated Exec Reports
Change emoji Auto-detect Activity Type
Auto-detect Activity Type
AI Signals & Alerts
AI Signals & Alerts
Change emoji AJA on Anything
AJA on Anything
Change emoji AI Call Scoring
AI Call Scoring
Jiminny MCP Connector
Jiminny MCP Connector
Desktop app to record a meetings without visible Notetaker
Desktop app to record a meetings without visible Notetaker
Feedback Change emoji
Feedback
Feedback
Research & User Feedback Change emoji
Research & User Feedback
Research & User Feedback
Create
Create
Jira , (opens new window)
Jira
, (opens new window)
Teams , (opens new window)
Teams
, (opens new window)
open menu
open menu
More
More
Side Navigation Drag Handle
Breadcrumbs
Jiminny MCP Connector
Updated 10m ago
Updated 10m ago
Overflow menu
2
Edit this content
Edit
Share, Open - Anyone in the space can edit
Share
Copy link
Copy link
More actions
More actions
Jiminny MCP Connector
Jiminny MCP Connector
Jiminny MCP Connector
By Galya Dimitrova
By Galya Dimitrova
Read time 12 min
12 min
Views 14
14
Add a reaction
Add a reaction
Epic
Link to Epik in Jira
Document status
DRAFT
Epic
Document status
Link to Epik in Jira
DRAFT
Change emoji Objective
Objective
Change emoji Objective
Enable customers to connect Jiminny data to external AI tools (Claude, OpenAI, Gemini) so it can be used as part of their broader knowledge base and workflows.
Position Jiminny as a
data layer for AI-driven revenue workflows
, not just a standalone product.
👤 Target user
👤 Target user
👤 Target user
Revenue teams using AI tools (Sales,
CS
, RevOps)
Companies already experimenting with Claude / OpenAI
Mid-market & Enterprise customers with multiple data sources (CRM, docs, CI tools, Support tools etc)
🤕 Pain point or problem
🤕
🤕
Pain point or problem
🤕 Pain point or problem
Jiminny data is locked in the platform
AI tools lack access to high-value conversation context
Customers must manually export/copy transcripts
No easy way to combine calls with CRM + docs + other info - using the Jiminny API is not suitable for non technical sales people...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20372] AI Reports > Empty page design and promotion - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20372] AI Reports > Empty page design and promotion - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny MCP Connector - Product - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny MCP Connector - Product - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Workers | Datadog","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Workers | Datadog","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20728] [HubSpot] Find the root cause of 429 hit and tweak API client rate limiter - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20728] [HubSpot] Find the root cause of 429 hit and tweak API client rate limiter - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Your 'Not enpough activities' report wasn't generated - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your 'Not enpough activities' report wasn't generated - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny MCP Connector - Product - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jiminny MCP Connector - Product - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.028819444,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.051736113,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.075,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.09826389,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.121527776,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said what is the oauth required for mcp for clauide code and claude chat","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"what is the oauth required for mcp for clauide code and claude chat","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"To understand the OAuth requirements for the Model Context Protocol (MCP) in Claude Code and Claude Chat, it helps to look at how MCP handles secure connections.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"MCP acts as a universal \"USB port\" that allows AI models to connect to external data sources and tools.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"When connecting to remote, HTTP-based MCP servers, Anthropic relies on the","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"OAuth 2.1","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"authorization framework.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This ensures that Claude can access your protected tools securely using temporary tokens, rather than requiring you to copy and paste long-lived API keys, passwords, or configuration secrets.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citations from Stytch, Model Context Protocol, and Zuplo. Opens side panel.","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"+2","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Here is exactly what is required and how OAuth is handled across both environments.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"The Underlying OAuth Flow for MCP","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Underlying OAuth Flow for MCP","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Whether you are using Claude Code or Claude Chat, the underlying architecture is identical.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Claude application acts as the","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"OAuth Client","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", and the remote tool you are connecting to acts as the","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resource Server","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Model Context Protocol. Opens side panel.","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"To build or connect to an MCP server, the OAuth integration must support this standard discovery and token exchange flow:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Initial Handshake (Discovery):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude attempts to connect to the MCP server without credentials. The server must reject this with a","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"401 Unauthorized","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"HTTP status and include a","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"WWW-Authenticate","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"header pointing to a Protected Resource Metadata (PRM) document.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Metadata Fetch:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude reads the PRM document to locate your specific Authorization Server (e.g., Okta, Auth0, Clerk, or a custom auth server).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Model Context Protocol. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Consent:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude prompts the user to authenticate.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The user is temporarily redirected to a browser window to log in and explicitly grant permission (e.g., \"Allow Claude to access your GitHub repositories\").","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citations from GitHub and Model Context Protocol. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"+1","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Token Exchange:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude receives a temporary authorization code via a redirect, which it silently exchanges for a long-lived access token.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Upstash. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Access Granted:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude now includes this token in the header of subsequent requests to invoke tools and read data on your behalf.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Model Context Protocol. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"MCP OAuth in Claude Code","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"MCP OAuth in Claude Code","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude Code is Anthropic's command-line interface (CLI) tool for software engineering. When you connect Claude Code to a protected remote MCP server, the OAuth flow is adapted for the terminal:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Browser Handoff:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"When Claude Code hits an MCP server that requires OAuth, it will generate a secure authorization link and automatically open your default desktop web browser (or output the URL to the terminal for headless environments).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Authentication:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Once you log in and approve access in the browser, the authorization server redirects the payload back to a local loopback port managed by Claude Code, handing off the authorization code.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Model Context Protocol. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Alternative (Static Headers):","depth":26,"bounds":{"left":0.23159721,"top":0.0,"width":0.15520833,"height":0.022777777},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If setting up a full OAuth 2.1 server is too complex for a quick internal tool, Claude Code also allows you to bypass the browser flow by injecting static bearer tokens directly via the CLI.","depth":26,"bounds":{"left":0.23159721,"top":0.0,"width":0.21875,"height":0.13833334},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can do this using the","depth":26,"bounds":{"left":0.23159721,"top":0.045,"width":0.20243056,"height":0.051666666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--header","depth":27,"bounds":{"left":0.36458334,"top":0.075555556,"width":0.046527777,"height":0.020555556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"flag (e.g.,","depth":26,"bounds":{"left":0.23159721,"top":0.07388889,"width":0.20868056,"height":0.051666666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"claude mcp add my-server --transport http --header \"Authorization: Bearer your-token\"","depth":27,"bounds":{"left":0.23159721,"top":0.104444444,"width":0.19826388,"height":0.07833333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":").","depth":26,"bounds":{"left":0.4340278,"top":0.16055556,"width":0.0069444445,"height":0.022777777},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from TrueFoundry. Opens side panel.","depth":26,"bounds":{"left":0.23576389,"top":0.19,"width":0.018055556,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"MCP OAuth in Claude Chat (Claude Desktop & Web)","depth":23,"bounds":{"left":0.20729166,"top":0.265,"width":0.24305555,"height":0.053333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"MCP OAuth in Claude Chat (Claude Desktop & Web)","depth":24,"bounds":{"left":0.20729166,"top":0.26722223,"width":0.24131945,"height":0.049444444},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"Claude Chat\" encompasses the visual interfaces—both the Claude Desktop application and the Claude.ai web platform.","depth":24,"bounds":{"left":0.20729166,"top":0.33055556,"width":0.21944444,"height":0.08055556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude.ai (Web Custom Connectors):","depth":26,"bounds":{"left":0.23159721,"top":0.4261111,"width":0.19930555,"height":0.022777777},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"When you add a remote MCP server via the \"Custom Connectors\" menu in your settings, Claude.ai handles the OAuth flow entirely in the browser. You simply paste the MCP server URL. Claude automatically parses the 401 discovery response and redirects you to the third-party service to grant permission, before seamlessly dropping you back into your chat session.","depth":26,"bounds":{"left":0.23159721,"top":0.4261111,"width":0.21875,"height":0.2827778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude Desktop:","depth":26,"bounds":{"left":0.23159721,"top":0.7238889,"width":0.08923611,"height":0.022777777},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude Desktop traditionally relies on a local configuration file (","depth":26,"bounds":{"left":0.23159721,"top":0.7238889,"width":0.21284722,"height":0.08055556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"claude_desktop_config.json","depth":27,"bounds":{"left":0.2579861,"top":0.78333336,"width":0.15138888,"height":0.020555556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"). While local stdio servers often require pasting API keys into this file, remote HTTP MCP servers utilizing OAuth eliminate this security risk.","depth":26,"bounds":{"left":0.23159721,"top":0.7816667,"width":0.21736111,"height":0.13833334},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"When Claude Desktop encounters an OAuth-protected server, it pops open your system's default browser to capture your consent.","depth":26,"bounds":{"left":0.23159721,"top":0.8972222,"width":0.21076389,"height":0.10277778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"It then stores the resulting token securely in your operating system's native keychain or credential manager, keeping your","depth":26,"bounds":{"left":0.23159721,"top":0.98388886,"width":0.21527778,"height":0.016111135},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"config.json","depth":27,"bounds":{"left":0.353125,"top":1.0,"width":0.06423611,"height":-0.07222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"free of sensitive plaintext passwords.","depth":26,"bounds":{"left":0.23159721,"top":1.0,"width":0.21597221,"height":-0.07055557},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from GitHub. Opens side panel.","depth":26,"bounds":{"left":0.39895833,"top":1.0,"width":0.018055556,"height":-0.100000024},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"The Bottom Line:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You do not need to build a bespoke authentication protocol for MCP.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your external tool already utilizes standard OpenID Connect or OAuth 2.0/2.1, Claude Code and Claude Chat are heavily standardized to automatically discover those endpoints, route the user for consent, and manage the resulting tokens behind the scenes.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from GitHub. Opens side panel.","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Enter a prompt for Gemini\nencrypted","depth":20,"value":"Enter a prompt for Gemini\nencrypted","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Enter a prompt for Gemini","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"encrypted","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Microphone","depth":19,"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.20034721,"top":0.0,"width":0.11180556,"height":0.035555556},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.21215278,"top":0.0,"width":0.088194445,"height":0.02111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Skip to:","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Top Bar","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Top Bar","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sidebar","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sidebar","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Main Content","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Main Content","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Collapse sidebar Ctrl [","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Collapse sidebar","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ctrl","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Switch sites or apps","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch sites or apps","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Confluence","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Search, press enter to navigate to advanced search with your text query","depth":11,"help_text":"","placeholder":"Search Confluence, Jira, Google Drive and other apps","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Create","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Rovo Ask Rovo","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Rovo","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Notifications","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Notifications","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"lukas.kovalik@jiminny.com","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"For you","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Recent","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Recent","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Starred","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Starred","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Spaces","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Spaces","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Apps","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Apps","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions","depth":14,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Back to top","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Back to top","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Content","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Content","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Create Create","depth":14,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Create","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Change view","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Change view","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Search by title","depth":15,"role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Results will update as you type.","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Strategy 2025+ Change emoji","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Product Strategy 2025+","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Product Strategy 2025+","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Competitive analysis Change emoji","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Competitive analysis","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Competitive analysis","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Ways of working - Product processes Change emoji","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Ways of working - Product processes","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Ways of working - Product processes","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Core Product Performance Metrics 📈","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Core Product Performance Metrics","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"📈","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Core Product Performance Metrics","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Documentation Change emoji","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Product Documentation","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Product Documentation","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Briefs Change emoji","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Product Briefs","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Product Briefs","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Activity Export","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity Export","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Autologging activities","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Autologging activities","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Deal Insights - Multiple currencies","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Deal Insights - Multiple currencies","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Reinvent Themes & Topics (and ACS)","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Reinvent Themes & Topics (and ACS)","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Billing Portal","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Billing Portal","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Upload Video/Audio Recordings","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Upload Video/Audio Recordings","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"White-Label Jiminny Instance","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"White-Label Jiminny Instance","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Win/Loss Analysis for a Deal","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Win/Loss Analysis for a Deal","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Hubspot app","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hubspot app","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Automatically hard delete data for churned customers","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Automatically hard delete data for churned customers","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Ask Jiminny Anything on Call level","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny Anything on Call level","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Ask Jiminny for Open and Closed Deals","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny for Open and Closed Deals","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Ask Jiminny Anything on Deal level","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny Anything on Deal level","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Automatically record all calendar meetings","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Automatically record all calendar meetings","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Product Tiering","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Tiering","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Recording Consent","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Recording Consent","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Automated CRM Filling","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Automated CRM Filling","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Automated Exec Reports","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Automated Exec Reports","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji Auto-detect Activity Type","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Auto-detect Activity Type","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"AI Signals & Alerts","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AI Signals & Alerts","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji AJA on Anything","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AJA on Anything","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Change emoji AI Call Scoring","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AI Call Scoring","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny MCP Connector","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny MCP Connector","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Desktop app to record a meetings without visible Notetaker","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Desktop app to record a meetings without visible Notetaker","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Feedback Change emoji","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Feedback","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Feedback","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Research & User Feedback Change emoji","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Research & User Feedback","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Research & User Feedback","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jira , (opens new window)","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jira","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", (opens new window)","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Teams , (opens new window)","depth":14,"bounds":{"left":0.48125,"top":0.0,"width":0.32152778,"height":0.035555556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Teams","depth":18,"bounds":{"left":0.5034722,"top":0.0,"width":0.030902777,"height":0.019444445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", (opens new window)","depth":16,"bounds":{"left":0.48125,"top":0.0,"width":0.10104167,"height":0.019444445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"open menu","depth":15,"bounds":{"left":0.77916664,"top":0.0,"width":0.008333334,"height":0.026666667},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"open menu","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More","depth":13,"bounds":{"left":0.48125,"top":0.0,"width":0.32152778,"height":0.035555556},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":16,"bounds":{"left":0.5034722,"top":0.0,"width":0.023958333,"height":0.019444445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Side Navigation Drag Handle","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Breadcrumbs","depth":15,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Jiminny MCP Connector","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Updated 10m ago","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Updated 10m ago","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Overflow menu","depth":18,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Edit this content","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Edit","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Share, Open - Anyone in the space can edit","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Share","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy link","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Copy link","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"More actions","depth":15,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More actions","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Jiminny MCP Connector","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny MCP Connector","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Jiminny MCP Connector","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"By Galya Dimitrova","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"By Galya Dimitrova","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Read time 12 min","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12 min","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Views 14","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"14","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add a reaction","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Add a reaction","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Epic","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Link to Epik in Jira","depth":22,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Document status","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DRAFT","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Epic","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Document status","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Link to Epik in Jira","depth":22,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DRAFT","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Change emoji Objective","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Objective","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Change emoji Objective","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Enable customers to connect Jiminny data to external AI tools (Claude, OpenAI, Gemini) so it can be used as part of their broader knowledge base and workflows.","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Position Jiminny as a","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"data layer for AI-driven revenue workflows","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", not just a standalone product.","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"👤 Target user","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"👤 Target user","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"👤 Target user","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Revenue teams using AI tools (Sales,","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CS","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", RevOps)","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Companies already experimenting with Claude / OpenAI","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Mid-market & Enterprise customers with multiple data sources (CRM, docs, CI tools, Support tools etc)","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"🤕 Pain point or problem","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"🤕","depth":16,"help_text":"https://emojipedia.org/face-with-head-bandage/","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"🤕","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pain point or problem","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"🤕 Pain point or problem","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny data is locked in the platform","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AI tools lack access to high-value conversation context","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Customers must manually export/copy transcripts","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No easy way to combine calls with CRM + docs + other info - using the Jiminny API is not suitable for non technical sales people","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-1465400497493528962
|
9087610414185280247
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
[JY-20372] AI Reports > Empty page design and promotion - Jira
[JY-20372] AI Reports > Empty page design and promotion - Jira
Jiminny MCP Connector - Product - Confluence
Jiminny MCP Connector - Product - Confluence
Jiminny
Jiminny
Workers | Datadog
Workers | Datadog
Pull requests · jiminny/app
Pull requests · jiminny/app
[JY-20728] [HubSpot] Find the root cause of 429 hit and tweak API client rate limiter - Jira
[JY-20728] [HubSpot] Find the root cause of 429 hit and tweak API client rate limiter - Jira
JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app
JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app
Jiminny
Jiminny
CloudWatch | us-east-2
CloudWatch | us-east-2
Your 'Not enpough activities' report wasn't generated - [EMAIL] - Jiminny Mail
Your 'Not enpough activities' report wasn't generated - [EMAIL] - Jiminny Mail
Jiminny MCP Connector - Product - Confluence
Jiminny MCP Connector - Product - Confluence
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said what is the oauth required for mcp for clauide code and claude chat
You said
what is the oauth required for mcp for clauide code and claude chat
Listen
Show more options
Show thinking
Gemini said
Gemini said
To understand the OAuth requirements for the Model Context Protocol (MCP) in Claude Code and Claude Chat, it helps to look at how MCP handles secure connections.
MCP acts as a universal "USB port" that allows AI models to connect to external data sources and tools.
When connecting to remote, HTTP-based MCP servers, Anthropic relies on the
OAuth 2.1
authorization framework.
This ensures that Claude can access your protected tools securely using temporary tokens, rather than requiring you to copy and paste long-lived API keys, passwords, or configuration secrets.
View source details for citations from Stytch, Model Context Protocol, and Zuplo. Opens side panel.
+2
Here is exactly what is required and how OAuth is handled across both environments.
The Underlying OAuth Flow for MCP
The Underlying OAuth Flow for MCP
Whether you are using Claude Code or Claude Chat, the underlying architecture is identical.
The Claude application acts as the
OAuth Client
, and the remote tool you are connecting to acts as the
Resource Server
.
View source details for citation from Model Context Protocol. Opens side panel.
To build or connect to an MCP server, the OAuth integration must support this standard discovery and token exchange flow:
Initial Handshake (Discovery):
Claude attempts to connect to the MCP server without credentials. The server must reject this with a
401 Unauthorized
HTTP status and include a
WWW-Authenticate
header pointing to a Protected Resource Metadata (PRM) document.
Metadata Fetch:
Claude reads the PRM document to locate your specific Authorization Server (e.g., Okta, Auth0, Clerk, or a custom auth server).
View source details for citation from Model Context Protocol. Opens side panel.
User Consent:
Claude prompts the user to authenticate.
The user is temporarily redirected to a browser window to log in and explicitly grant permission (e.g., "Allow Claude to access your GitHub repositories").
View source details for citations from GitHub and Model Context Protocol. Opens side panel.
+1
Token Exchange:
Claude receives a temporary authorization code via a redirect, which it silently exchanges for a long-lived access token.
View source details for citation from Upstash. Opens side panel.
Access Granted:
Claude now includes this token in the header of subsequent requests to invoke tools and read data on your behalf.
View source details for citation from Model Context Protocol. Opens side panel.
MCP OAuth in Claude Code
MCP OAuth in Claude Code
Claude Code is Anthropic's command-line interface (CLI) tool for software engineering. When you connect Claude Code to a protected remote MCP server, the OAuth flow is adapted for the terminal:
Browser Handoff:
When Claude Code hits an MCP server that requires OAuth, it will generate a secure authorization link and automatically open your default desktop web browser (or output the URL to the terminal for headless environments).
Authentication:
Once you log in and approve access in the browser, the authorization server redirects the payload back to a local loopback port managed by Claude Code, handing off the authorization code.
View source details for citation from Model Context Protocol. Opens side panel.
Alternative (Static Headers):
If setting up a full OAuth 2.1 server is too complex for a quick internal tool, Claude Code also allows you to bypass the browser flow by injecting static bearer tokens directly via the CLI.
You can do this using the
--header
flag (e.g.,
claude mcp add my-server --transport http --header "Authorization: Bearer your-token"
).
View source details for citation from TrueFoundry. Opens side panel.
MCP OAuth in Claude Chat (Claude Desktop & Web)
MCP OAuth in Claude Chat (Claude Desktop & Web)
"Claude Chat" encompasses the visual interfaces—both the Claude Desktop application and the Claude.ai web platform.
Claude.ai (Web Custom Connectors):
When you add a remote MCP server via the "Custom Connectors" menu in your settings, Claude.ai handles the OAuth flow entirely in the browser. You simply paste the MCP server URL. Claude automatically parses the 401 discovery response and redirects you to the third-party service to grant permission, before seamlessly dropping you back into your chat session.
Claude Desktop:
Claude Desktop traditionally relies on a local configuration file (
claude_desktop_config.json
). While local stdio servers often require pasting API keys into this file, remote HTTP MCP servers utilizing OAuth eliminate this security risk.
When Claude Desktop encounters an OAuth-protected server, it pops open your system's default browser to capture your consent.
It then stores the resulting token securely in your operating system's native keychain or credential manager, keeping your
config.json
free of sensitive plaintext passwords.
View source details for citation from GitHub. Opens side panel.
The Bottom Line:
You do not need to build a bespoke authentication protocol for MCP.
If your external tool already utilizes standard OpenID Connect or OAuth 2.0/2.1, Claude Code and Claude Chat are heavily standardized to automatically discover those endpoints, route the user for consent, and manage the resulting tokens behind the scenes.
View source details for citation from GitHub. Opens side panel.
Sources
Sources
Enter a prompt for Gemini
encrypted
Enter a prompt for Gemini
encrypted
Open upload file menu
Tools
Open mode picker
Pro
Microphone
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Skip to:
Top Bar
Top Bar
Sidebar
Sidebar
Main Content
Main Content
Collapse sidebar Ctrl [
Collapse sidebar
Ctrl
[
Switch sites or apps
Switch sites or apps
Confluence
Search, press enter to navigate to advanced search with your text query
Create
Create
Rovo Ask Rovo
Ask Rovo
Notifications
Notifications
Help
Help
[EMAIL]
[EMAIL]
For you
For you
Recent
Recent
Starred
Starred
Spaces
Spaces
Apps
Apps
Product
Product
More actions
More actions
Back to top
Back to top
Content
Content
Create Create
Create
Change view
Change view
Search by title
Results will update as you type.
Product Strategy 2025+ Change emoji
Product Strategy 2025+
Product Strategy 2025+
Competitive analysis Change emoji
Competitive analysis
Competitive analysis
Ways of working - Product processes Change emoji
Ways of working - Product processes
Ways of working - Product processes
Core Product Performance Metrics 📈
Core Product Performance Metrics
📈
Core Product Performance Metrics
Product Documentation Change emoji
Product Documentation
Product Documentation
Product Briefs Change emoji
Product Briefs
Product Briefs
Change emoji Activity Export
Activity Export
Change emoji Autologging activities
Autologging activities
Deal Insights - Multiple currencies
Deal Insights - Multiple currencies
Reinvent Themes & Topics (and ACS)
Reinvent Themes & Topics (and ACS)
Change emoji Billing Portal
Billing Portal
Change emoji Upload Video/Audio Recordings
Upload Video/Audio Recordings
White-Label Jiminny Instance
White-Label Jiminny Instance
Win/Loss Analysis for a Deal
Win/Loss Analysis for a Deal
Change emoji Hubspot app
Hubspot app
Change emoji Automatically hard delete data for churned customers
Automatically hard delete data for churned customers
Change emoji Ask Jiminny Anything on Call level
Ask Jiminny Anything on Call level
Change emoji Ask Jiminny for Open and Closed Deals
Ask Jiminny for Open and Closed Deals
Change emoji Ask Jiminny Anything on Deal level
Ask Jiminny Anything on Deal level
Change emoji Automatically record all calendar meetings
Automatically record all calendar meetings
Change emoji Product Tiering
Product Tiering
Change emoji Recording Consent
Recording Consent
Change emoji Automated CRM Filling
Automated CRM Filling
Change emoji Automated Exec Reports
Automated Exec Reports
Change emoji Auto-detect Activity Type
Auto-detect Activity Type
AI Signals & Alerts
AI Signals & Alerts
Change emoji AJA on Anything
AJA on Anything
Change emoji AI Call Scoring
AI Call Scoring
Jiminny MCP Connector
Jiminny MCP Connector
Desktop app to record a meetings without visible Notetaker
Desktop app to record a meetings without visible Notetaker
Feedback Change emoji
Feedback
Feedback
Research & User Feedback Change emoji
Research & User Feedback
Research & User Feedback
Create
Create
Jira , (opens new window)
Jira
, (opens new window)
Teams , (opens new window)
Teams
, (opens new window)
open menu
open menu
More
More
Side Navigation Drag Handle
Breadcrumbs
Jiminny MCP Connector
Updated 10m ago
Updated 10m ago
Overflow menu
2
Edit this content
Edit
Share, Open - Anyone in the space can edit
Share
Copy link
Copy link
More actions
More actions
Jiminny MCP Connector
Jiminny MCP Connector
Jiminny MCP Connector
By Galya Dimitrova
By Galya Dimitrova
Read time 12 min
12 min
Views 14
14
Add a reaction
Add a reaction
Epic
Link to Epik in Jira
Document status
DRAFT
Epic
Document status
Link to Epik in Jira
DRAFT
Change emoji Objective
Objective
Change emoji Objective
Enable customers to connect Jiminny data to external AI tools (Claude, OpenAI, Gemini) so it can be used as part of their broader knowledge base and workflows.
Position Jiminny as a
data layer for AI-driven revenue workflows
, not just a standalone product.
👤 Target user
👤 Target user
👤 Target user
Revenue teams using AI tools (Sales,
CS
, RevOps)
Companies already experimenting with Claude / OpenAI
Mid-market & Enterprise customers with multiple data sources (CRM, docs, CI tools, Support tools etc)
🤕 Pain point or problem
🤕
🤕
Pain point or problem
🤕 Pain point or problem
Jiminny data is locked in the platform
AI tools lack access to high-value conversation context
Customers must manually export/copy transcripts
No easy way to combine calls with CRM + docs + other info - using the Jiminny API is not suitable for non technical sales people...
|
71968
|
|
54854
|
1183
|
57
|
2026-04-20T09:21:34.256964+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-20/1776 /Users/lukas/.screenpipe/data/data/2026-04-20/1776676894256_m1.jpg...
|
Firefox
|
Jiminny — Work
|
1
|
app.dev.jiminny.com/ai-reports/manage
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
New Tab
New Tab
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Userpilot | Logged-activity
Userpilot | Logged-activity
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Jiminny
Jiminny
Close tab
Jiminny
Jiminny
Jiminny
Jiminny
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Ask Jiminny Reports
Ask Jiminny Reports
Create
Report name
Prompt Prompt
Prompt
Prompt
Saved search Saved search
Saved search
Saved search
All statuses All statuses
All statuses
All statuses
Clear all
NAME
FREQUENCY
SHARED
EXPIRING
ACTIONS
Exp
Daily
20/04/2027
Monthly Ask J Report
Monthly
Jiminny Mobile SA
30/06/2026
Search One
Daily
Jiminny Mobile SA
30/04/2026
Edit report
Save
1. General
1. General
NAME
Exp
Clear
*
FREQUENCY
Select
Select
*
EXPIRES ON
20 Apr, 2027
*
Share with
TEAM
Select Select
Select
Select
TEAM MEMBER
Select Select
Select
Select
2. Report parameters
2. Report parameters
SAVED SEARCH
Select group one
Select
group one
*
ASK JIMINNY PROMPT
Select Lets test it
Select
Lets test it
*
Report definition saved
Close notification
Clear
Filter URLs
Pause/Resume recording network log
New Request
Search
Request Blocking
All
HTML
CSS
JS
XHR
Fonts
Images
Media
WS
Other
Disable Cache
Disable Cache
No Throttling
Network Settings
Status
Status
Method
Method
Domain
Domain
File
File
Initiator
Initiator
Type
Type
Transferred
Transferred
Size
Size
0 ms
0 ms
200
GET
app.dev.jiminny.com
form-data
xhr
json
7.56 kB
10.67 kB
589 ms
200
POST
app.dev.jiminny.com
aj-reports
xhr
json
3.03 kB
493 B
496 ms
200
GET
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
json
7.57 kB
10.83 kB
406 ms
Status
Status
200
Method
Method
GET
Domain
Domain
app.dev.jiminny.com
File
File
form-data
Initiator
Initiator
xhr
Type
Type
json
Transferred
Transferred
7.56 kB
Size
Size
10.67 kB
0 ms
0 ms
589 ms
Start performance analysis
3 requests
21.99 kB / 18.16 kB transferred
Finish: 30.62 s...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Product Growth Platform | Userpilot","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Growth Platform | Userpilot","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Userpilot | Logged-activity","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Userpilot | Logged-activity","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Ask Jiminny Reports","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ask Jiminny Reports","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"Report name","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Prompt Prompt","depth":10,"value":"Prompt Prompt","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Prompt","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Prompt","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Saved search Saved search","depth":10,"value":"Saved search Saved search","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Saved search","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Saved search","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"All statuses All statuses","depth":10,"value":"All statuses All statuses","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"All statuses","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All statuses","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Clear all","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"NAME","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FREQUENCY","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SHARED","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EXPIRING","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIONS","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Exp","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20/04/2027","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Monthly Ask J Report","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Monthly","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny Mobile SA","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30/06/2026","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search One","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny Mobile SA","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30/04/2026","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Edit report","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Save","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"1. General","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. General","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NAME","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Exp","depth":12,"value":"Exp","help_text":"","placeholder":"Enter name","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Clear","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"*","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FREQUENCY","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select","depth":11,"value":"Select","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"*","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EXPIRES ON","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20 Apr, 2027","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Share with","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TEAM","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Select","depth":11,"value":"Select Select","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TEAM MEMBER","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Select","depth":11,"value":"Select Select","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. Report parameters","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. Report parameters","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SAVED SEARCH","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select group one","depth":11,"value":"Select group one","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"group one","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ASK JIMINNY PROMPT","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Lets test it","depth":11,"value":"Select Lets test it","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lets test it","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Report definition saved","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close notification","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Clear","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"Filter URLs","depth":16,"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Pause/Resume recording network log","depth":16,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"New Request","depth":16,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Search","depth":16,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Request Blocking","depth":16,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"All","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"HTML","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"CSS","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"JS","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"XHR","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Fonts","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Images","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Media","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"WS","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Other","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Disable Cache","depth":17,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Disable Cache","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"No Throttling","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Network Settings","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Status","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Method","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Method","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Domain","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Domain","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"File","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"File","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Initiator","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Initiator","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Type","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Transferred","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Transferred","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Size","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Size","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"0 ms","depth":24,"help_text":"Timeline","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0 ms","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"form-data","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.56 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.67 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"589 ms","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POST","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"aj-reports","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3.03 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"493 B","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"496 ms","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7361706f-ffbe-4d3d-a22b-9fab33d05094","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.57 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.83 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"406 ms","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Status","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Method","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Method","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Domain","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Domain","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"File","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"File","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"form-data","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Initiator","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Initiator","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Type","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Transferred","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Transferred","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.56 kB","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Size","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Size","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.67 kB","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"0 ms","depth":23,"help_text":"Timeline","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0 ms","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"589 ms","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start performance analysis","depth":20,"bounds":{"left":0.5694444,"top":0.0,"width":0.016666668,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3 requests","depth":21,"bounds":{"left":0.59375,"top":0.0,"width":0.038541667,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21.99 kB / 18.16 kB transferred","depth":21,"bounds":{"left":0.646875,"top":0.0,"width":0.11597222,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finish: 30.62 s","depth":21,"bounds":{"left":0.77743053,"top":0.0,"width":0.054166667,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
9087983999674122723
|
9085277777879295671
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
New Tab
New Tab
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Userpilot | Logged-activity
Userpilot | Logged-activity
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Jiminny
Jiminny
Close tab
Jiminny
Jiminny
Jiminny
Jiminny
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Ask Jiminny Reports
Ask Jiminny Reports
Create
Report name
Prompt Prompt
Prompt
Prompt
Saved search Saved search
Saved search
Saved search
All statuses All statuses
All statuses
All statuses
Clear all
NAME
FREQUENCY
SHARED
EXPIRING
ACTIONS
Exp
Daily
20/04/2027
Monthly Ask J Report
Monthly
Jiminny Mobile SA
30/06/2026
Search One
Daily
Jiminny Mobile SA
30/04/2026
Edit report
Save
1. General
1. General
NAME
Exp
Clear
*
FREQUENCY
Select
Select
*
EXPIRES ON
20 Apr, 2027
*
Share with
TEAM
Select Select
Select
Select
TEAM MEMBER
Select Select
Select
Select
2. Report parameters
2. Report parameters
SAVED SEARCH
Select group one
Select
group one
*
ASK JIMINNY PROMPT
Select Lets test it
Select
Lets test it
*
Report definition saved
Close notification
Clear
Filter URLs
Pause/Resume recording network log
New Request
Search
Request Blocking
All
HTML
CSS
JS
XHR
Fonts
Images
Media
WS
Other
Disable Cache
Disable Cache
No Throttling
Network Settings
Status
Status
Method
Method
Domain
Domain
File
File
Initiator
Initiator
Type
Type
Transferred
Transferred
Size
Size
0 ms
0 ms
200
GET
app.dev.jiminny.com
form-data
xhr
json
7.56 kB
10.67 kB
589 ms
200
POST
app.dev.jiminny.com
aj-reports
xhr
json
3.03 kB
493 B
496 ms
200
GET
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
json
7.57 kB
10.83 kB
406 ms
Status
Status
200
Method
Method
GET
Domain
Domain
app.dev.jiminny.com
File
File
form-data
Initiator
Initiator
xhr
Type
Type
json
Transferred
Transferred
7.56 kB
Size
Size
10.67 kB
0 ms
0 ms
589 ms
Start performance analysis
3 requests
21.99 kB / 18.16 kB transferred
Finish: 30.62 s...
|
NULL
|
|
54855
|
1184
|
67
|
2026-04-20T09:21:34.174635+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-20/1776 /Users/lukas/.screenpipe/data/data/2026-04-20/1776676894174_m2.jpg...
|
Firefox
|
Jiminny — Work
|
1
|
app.dev.jiminny.com/ai-reports/manage
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
New Tab
New Tab
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Userpilot | Logged-activity
Userpilot | Logged-activity
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Jiminny
Jiminny
Close tab
Jiminny
Jiminny
Jiminny
Jiminny
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Ask Jiminny Reports
Ask Jiminny Reports
Create
Report name
Prompt Prompt
Prompt
Prompt
Saved search Saved search
Saved search
Saved search
All statuses All statuses
All statuses
All statuses
Clear all
NAME
FREQUENCY
SHARED
EXPIRING
ACTIONS
Exp
Daily
20/04/2027
Monthly Ask J Report
Monthly
Jiminny Mobile SA
30/06/2026
Search One
Daily
Jiminny Mobile SA
30/04/2026
Edit report
Save
1. General
1. General
NAME
Exp
Clear
*
FREQUENCY
Select
Select
*
EXPIRES ON
20 Apr, 2027
*
Share with
TEAM
Select Select
Select
Select
TEAM MEMBER
Select Select
Select
Select
2. Report parameters
2. Report parameters
SAVED SEARCH
Select group one
Select
group one
*
ASK JIMINNY PROMPT
Select Lets test it
Select
Lets test it
*
Report definition saved
Close notification
Clear
Filter URLs
Pause/Resume recording network log
New Request
Search
Request Blocking
All
HTML
CSS
JS
XHR
Fonts
Images
Media
WS
Other
Disable Cache
Disable Cache
No Throttling
Network Settings
Status
Status
Method
Method
Domain
Domain
File
File
Initiator
Initiator
Type
Type
Transferred
Transferred
Size
Size
0 ms
0 ms
200
GET
app.dev.jiminny.com
form-data
xhr
json
7.56 kB
10.67 kB
589 ms
200
POST
app.dev.jiminny.com
aj-reports
xhr
json
3.03 kB
493 B
496 ms
200
GET
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
json
7.57 kB
10.83 kB
406 ms
Status
Status
200
Method
Method
GET
Domain
Domain
app.dev.jiminny.com
File
File
form-data
Initiator
Initiator
xhr
Type
Type
json
Transferred
Transferred
7.56 kB
Size
Size
10.67 kB
0 ms
0 ms
589 ms
Start performance analysis
3 requests
21.99 kB / 18.16 kB transferred
Finish: 30.62 s...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0018284575,"top":0.0518755,"width":0.07596409,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.09497207,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.10614525,"width":0.15774602,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"bounds":{"left":0.0,"top":0.12769353,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.13886672,"width":0.09524601,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.16041501,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.17158818,"width":0.19963431,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19313647,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.20430966,"width":0.15525267,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":4,"bounds":{"left":0.0,"top":0.22585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.23703113,"width":0.06981383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":4,"bounds":{"left":0.0,"top":0.2585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.2697526,"width":0.10688165,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.29130086,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.30247405,"width":0.12915559,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.32402235,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.013297873,"top":0.33519554,"width":0.014960106,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Product Growth Platform | Userpilot","depth":4,"bounds":{"left":0.0,"top":0.3567438,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Growth Platform | Userpilot","depth":5,"bounds":{"left":0.013297873,"top":0.367917,"width":0.06200133,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Userpilot | Logged-activity","depth":4,"bounds":{"left":0.0,"top":0.38946527,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Userpilot | Logged-activity","depth":5,"bounds":{"left":0.013297873,"top":0.40063846,"width":0.04637633,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.42218676,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.43335995,"width":0.2052859,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.45490822,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.4660814,"width":0.039228722,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.0,"top":0.48762968,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.013297873,"top":0.49880287,"width":0.042719416,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.5203512,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.53152436,"width":0.2052859,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.55307263,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.5642458,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.5602554,"width":0.007978723,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.5857941,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.5969673,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.61851555,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.62968874,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.6528332,"width":0.07413564,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Ask Jiminny Reports","depth":10,"bounds":{"left":0.10887633,"top":0.06943336,"width":0.06000665,"height":0.019553073},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ask Jiminny Reports","depth":11,"bounds":{"left":0.10887633,"top":0.06943336,"width":0.06000665,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create","depth":10,"bounds":{"left":0.5103058,"top":0.06464485,"width":0.023271276,"height":0.028731046},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"Report name","depth":11,"bounds":{"left":0.12134308,"top":0.10933759,"width":0.058011968,"height":0.019952115},"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Prompt Prompt","depth":10,"bounds":{"left":0.19930187,"top":0.10933759,"width":0.0731383,"height":0.019952115},"value":"Prompt Prompt","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Prompt","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Prompt","depth":12,"bounds":{"left":0.19930187,"top":0.11292897,"width":0.01462766,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Saved search Saved search","depth":10,"bounds":{"left":0.28041887,"top":0.10933759,"width":0.0731383,"height":0.019952115},"value":"Saved search Saved search","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Saved search","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Saved search","depth":12,"bounds":{"left":0.28041887,"top":0.11292897,"width":0.025099734,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"All statuses All statuses","depth":10,"bounds":{"left":0.3615359,"top":0.10933759,"width":0.059840426,"height":0.019952115},"value":"All statuses All statuses","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"All statuses","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All statuses","depth":12,"bounds":{"left":0.3615359,"top":0.11292897,"width":0.022273935,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Clear all","depth":10,"bounds":{"left":0.42503324,"top":0.112529926,"width":0.024268618,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"NAME","depth":12,"bounds":{"left":0.10854388,"top":0.16679968,"width":0.012965426,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FREQUENCY","depth":12,"bounds":{"left":0.2521609,"top":0.16679968,"width":0.026097074,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SHARED","depth":12,"bounds":{"left":0.32396942,"top":0.16679968,"width":0.017453458,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EXPIRING","depth":12,"bounds":{"left":0.3956117,"top":0.16679968,"width":0.02044548,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIONS","depth":12,"bounds":{"left":0.46742022,"top":0.16679968,"width":0.019115692,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Exp","depth":14,"bounds":{"left":0.10854388,"top":0.207502,"width":0.00731383,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily","depth":14,"bounds":{"left":0.2521609,"top":0.207502,"width":0.010139627,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20/04/2027","depth":14,"bounds":{"left":0.3956117,"top":0.207502,"width":0.024102394,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Monthly Ask J Report","depth":14,"bounds":{"left":0.10854388,"top":0.2462091,"width":0.042220745,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Monthly","depth":14,"bounds":{"left":0.2521609,"top":0.2462091,"width":0.01662234,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny Mobile SA","depth":15,"bounds":{"left":0.33111703,"top":0.23902634,"width":0.015957447,"height":0.04309657},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30/06/2026","depth":14,"bounds":{"left":0.3956117,"top":0.2462091,"width":0.024102394,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search One","depth":14,"bounds":{"left":0.10854388,"top":0.28451717,"width":0.022606382,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily","depth":14,"bounds":{"left":0.2521609,"top":0.28451717,"width":0.010139627,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny Mobile SA","depth":15,"bounds":{"left":0.33111703,"top":0.2773344,"width":0.015957447,"height":0.04309657},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30/04/2026","depth":14,"bounds":{"left":0.3956117,"top":0.28451717,"width":0.024102394,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Edit report","depth":13,"bounds":{"left":0.34208778,"top":0.06943336,"width":0.032247342,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Save","depth":12,"bounds":{"left":0.5021609,"top":0.06464485,"width":0.018783245,"height":0.028731046},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"1. General","depth":11,"bounds":{"left":0.34208778,"top":0.12609737,"width":0.19414894,"height":0.032721467},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. General","depth":12,"bounds":{"left":0.34208778,"top":0.13248204,"width":0.024601065,"height":0.01556265},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NAME","depth":13,"bounds":{"left":0.3464096,"top":0.16799681,"width":0.009973404,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Exp","depth":12,"bounds":{"left":0.3464096,"top":0.17797287,"width":0.1775266,"height":0.019952115},"value":"Exp","help_text":"","placeholder":"Enter name","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Clear","depth":12,"bounds":{"left":0.52393615,"top":0.1783719,"width":0.007978723,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"*","depth":12,"bounds":{"left":0.53125,"top":0.16241021,"width":0.0026595744,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FREQUENCY","depth":13,"bounds":{"left":0.3464096,"top":0.22306465,"width":0.020279255,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select","depth":11,"bounds":{"left":0.3464096,"top":0.2330407,"width":0.09075798,"height":0.019952115},"value":"Select","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXTextField","text":"Select","depth":12,"bounds":{"left":0.3464096,"top":0.23503591,"width":0.080784574,"height":0.015961692},"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"*","depth":12,"bounds":{"left":0.4325133,"top":0.21747805,"width":0.0026595744,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EXPIRES ON","depth":15,"bounds":{"left":0.44514626,"top":0.22306465,"width":0.019281914,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20 Apr, 2027","depth":15,"bounds":{"left":0.44514626,"top":0.2386273,"width":0.024933511,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":14,"bounds":{"left":0.53125,"top":0.21747805,"width":0.0026595744,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Share with","depth":12,"bounds":{"left":0.34208778,"top":0.27094972,"width":0.022107713,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TEAM","depth":13,"bounds":{"left":0.3464096,"top":0.2980846,"width":0.009474734,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Select","depth":11,"bounds":{"left":0.3464096,"top":0.30806065,"width":0.09075798,"height":0.019952115},"value":"Select Select","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select","depth":13,"bounds":{"left":0.3464096,"top":0.31165203,"width":0.011801862,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TEAM MEMBER","depth":13,"bounds":{"left":0.44514626,"top":0.2980846,"width":0.024601065,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Select","depth":11,"bounds":{"left":0.44514626,"top":0.30806065,"width":0.09075798,"height":0.019952115},"value":"Select Select","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select","depth":13,"bounds":{"left":0.44514626,"top":0.31165203,"width":0.011801862,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. Report parameters","depth":11,"bounds":{"left":0.34208778,"top":0.34477255,"width":0.19414894,"height":0.032721467},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. Report parameters","depth":12,"bounds":{"left":0.34208778,"top":0.35115722,"width":0.05119681,"height":0.01556265},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SAVED SEARCH","depth":13,"bounds":{"left":0.3464096,"top":0.386672,"width":0.02443484,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select group one","depth":11,"bounds":{"left":0.3464096,"top":0.39664805,"width":0.09075798,"height":0.019952115},"value":"Select group one","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"group one","depth":13,"bounds":{"left":0.3464096,"top":0.40023944,"width":0.019448139,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":12,"bounds":{"left":0.4325133,"top":0.3810854,"width":0.0026595744,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ASK JIMINNY PROMPT","depth":13,"bounds":{"left":0.44514626,"top":0.386672,"width":0.035904255,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Lets test it","depth":11,"bounds":{"left":0.44514626,"top":0.39664805,"width":0.09075798,"height":0.019952115},"value":"Select Lets test it","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lets test it","depth":13,"bounds":{"left":0.44514626,"top":0.40023944,"width":0.020279255,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":12,"bounds":{"left":0.53125,"top":0.3810854,"width":0.0026595744,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Report definition saved","depth":11,"bounds":{"left":0.10073138,"top":0.95730245,"width":0.04837101,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close notification","depth":10,"bounds":{"left":0.20246011,"top":0.95610535,"width":0.0066489363,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Clear","depth":16,"bounds":{"left":0.54288566,"top":0.07821229,"width":0.008643617,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"Filter URLs","depth":16,"bounds":{"left":0.5531915,"top":0.07581804,"width":0.18517287,"height":0.0207502},"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Pause/Resume recording network log","depth":16,"bounds":{"left":0.75199467,"top":0.077813245,"width":0.008643617,"height":0.016759777},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"New Request","depth":16,"bounds":{"left":0.7613032,"top":0.07821229,"width":0.008643617,"height":0.015961692},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Search","depth":16,"bounds":{"left":0.7706117,"top":0.07821229,"width":0.008643617,"height":0.015961692},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Request Blocking","depth":16,"bounds":{"left":0.7799202,"top":0.07821229,"width":0.008643617,"height":0.015961692},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"All","depth":17,"bounds":{"left":0.7925532,"top":0.07861133,"width":0.00831117,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"HTML","depth":17,"bounds":{"left":0.8015292,"top":0.07861133,"width":0.014295213,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"CSS","depth":17,"bounds":{"left":0.81648934,"top":0.07861133,"width":0.011469414,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"JS","depth":17,"bounds":{"left":0.82862365,"top":0.07861133,"width":0.00831117,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"XHR","depth":17,"bounds":{"left":0.83759975,"top":0.07861133,"width":0.011635638,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Fonts","depth":17,"bounds":{"left":0.84990025,"top":0.07861133,"width":0.013630319,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Images","depth":17,"bounds":{"left":0.86419547,"top":0.07861133,"width":0.01662234,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Media","depth":17,"bounds":{"left":0.8814827,"top":0.07861133,"width":0.014461436,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"WS","depth":17,"bounds":{"left":0.89660907,"top":0.07861133,"width":0.009973404,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Other","depth":17,"bounds":{"left":0.90724736,"top":0.07861133,"width":0.013796543,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Disable Cache","depth":17,"bounds":{"left":0.92669547,"top":0.080207504,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Disable Cache","depth":17,"bounds":{"left":0.93234706,"top":0.08100559,"width":0.024933511,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"No Throttling","depth":16,"bounds":{"left":0.9609375,"top":0.07940942,"width":0.027094414,"height":0.01396648},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Network Settings","depth":16,"bounds":{"left":0.9896942,"top":0.07821229,"width":0.008643617,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Status","depth":24,"bounds":{"left":0.5415558,"top":0.0981644,"width":0.027593086,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status","depth":26,"bounds":{"left":0.5432181,"top":0.10295291,"width":0.011136968,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Method","depth":24,"bounds":{"left":0.5694814,"top":0.0981644,"width":0.027260639,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Method","depth":26,"bounds":{"left":0.5711436,"top":0.10295291,"width":0.013297873,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Domain","depth":24,"bounds":{"left":0.59707445,"top":0.0981644,"width":0.06981383,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Domain","depth":26,"bounds":{"left":0.5987367,"top":0.10295291,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"File","depth":24,"bounds":{"left":0.6672208,"top":0.0981644,"width":0.1377992,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"File","depth":26,"bounds":{"left":0.66888297,"top":0.10295291,"width":0.006150266,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Initiator","depth":24,"bounds":{"left":0.8053524,"top":0.0981644,"width":0.054853722,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Initiator","depth":26,"bounds":{"left":0.80701464,"top":0.10295291,"width":0.013297873,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Type","depth":24,"bounds":{"left":0.86053854,"top":0.0981644,"width":0.027260639,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":26,"bounds":{"left":0.8622008,"top":0.10295291,"width":0.008477394,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Transferred","depth":24,"bounds":{"left":0.8881317,"top":0.0981644,"width":0.006150266,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Transferred","depth":26,"bounds":{"left":0.8897939,"top":0.10295291,"width":0.020279255,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Size","depth":24,"bounds":{"left":0.89461434,"top":0.0981644,"width":0.08277926,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Size","depth":26,"bounds":{"left":0.8962766,"top":0.10295291,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"0 ms","depth":24,"bounds":{"left":0.97772604,"top":0.0981644,"width":0.021941489,"height":0.01915403},"help_text":"Timeline","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0 ms","depth":27,"bounds":{"left":0.9790558,"top":0.105347164,"width":0.0066489363,"height":0.007980846},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"bounds":{"left":0.54388297,"top":0.12290503,"width":0.006482713,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":24,"bounds":{"left":0.5711436,"top":0.122505985,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"bounds":{"left":0.6037234,"top":0.122505985,"width":0.03507314,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"form-data","depth":25,"bounds":{"left":0.66888297,"top":0.122505985,"width":0.017453458,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"bounds":{"left":0.80701464,"top":0.122505985,"width":0.005485372,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"bounds":{"left":0.8622008,"top":0.122505985,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.56 kB","depth":24,"bounds":{"left":0.8897939,"top":0.122505985,"width":0.012799202,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.67 kB","depth":24,"bounds":{"left":0.96127,"top":0.122505985,"width":0.014793883,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"589 ms","depth":25,"bounds":{"left":0.9793883,"top":0.12330407,"width":0.011303191,"height":0.008778931},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"bounds":{"left":0.54388297,"top":0.14205906,"width":0.006482713,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POST","depth":24,"bounds":{"left":0.5711436,"top":0.14166002,"width":0.009807181,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"bounds":{"left":0.6037234,"top":0.14166002,"width":0.03507314,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"aj-reports","depth":25,"bounds":{"left":0.66888297,"top":0.14166002,"width":0.017287234,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"bounds":{"left":0.80701464,"top":0.14166002,"width":0.005485372,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"bounds":{"left":0.8622008,"top":0.14166002,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3.03 kB","depth":24,"bounds":{"left":0.8897939,"top":0.14166002,"width":0.013297873,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"493 B","depth":24,"bounds":{"left":0.9655917,"top":0.14166002,"width":0.010472074,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"496 ms","depth":25,"bounds":{"left":0.9878657,"top":0.1424581,"width":0.011136968,"height":0.008778931},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"bounds":{"left":0.54388297,"top":0.16121309,"width":0.006482713,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":24,"bounds":{"left":0.5711436,"top":0.16081405,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"bounds":{"left":0.6037234,"top":0.16081405,"width":0.03507314,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7361706f-ffbe-4d3d-a22b-9fab33d05094","depth":25,"bounds":{"left":0.66888297,"top":0.16081405,"width":0.07480053,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"bounds":{"left":0.80701464,"top":0.16081405,"width":0.005485372,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"bounds":{"left":0.8622008,"top":0.16081405,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.57 kB","depth":24,"bounds":{"left":0.8897939,"top":0.16081405,"width":0.012632979,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.83 kB","depth":24,"bounds":{"left":0.96110374,"top":0.16081405,"width":0.014960106,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"406 ms","depth":25,"bounds":{"left":0.98952794,"top":0.16161214,"width":0.010472059,"height":0.008778931},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Status","depth":23,"bounds":{"left":0.5415558,"top":0.0981644,"width":0.027593086,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status","depth":25,"bounds":{"left":0.5432181,"top":0.10295291,"width":0.011136968,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":23,"bounds":{"left":0.54388297,"top":0.12290503,"width":0.006482713,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Method","depth":23,"bounds":{"left":0.5694814,"top":0.0981644,"width":0.027260639,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Method","depth":25,"bounds":{"left":0.5711436,"top":0.10295291,"width":0.013297873,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":23,"bounds":{"left":0.5711436,"top":0.122505985,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Domain","depth":23,"bounds":{"left":0.59707445,"top":0.0981644,"width":0.06981383,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Domain","depth":25,"bounds":{"left":0.5987367,"top":0.10295291,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":23,"bounds":{"left":0.6037234,"top":0.122505985,"width":0.03507314,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"File","depth":23,"bounds":{"left":0.6672208,"top":0.0981644,"width":0.1377992,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"File","depth":25,"bounds":{"left":0.66888297,"top":0.10295291,"width":0.006150266,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"form-data","depth":24,"bounds":{"left":0.66888297,"top":0.122505985,"width":0.017453458,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Initiator","depth":23,"bounds":{"left":0.8053524,"top":0.0981644,"width":0.054853722,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Initiator","depth":25,"bounds":{"left":0.80701464,"top":0.10295291,"width":0.013297873,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":23,"bounds":{"left":0.80701464,"top":0.122505985,"width":0.005485372,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Type","depth":23,"bounds":{"left":0.86053854,"top":0.0981644,"width":0.027260639,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":25,"bounds":{"left":0.8622008,"top":0.10295291,"width":0.008477394,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":23,"bounds":{"left":0.8622008,"top":0.122505985,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Transferred","depth":23,"bounds":{"left":0.8881317,"top":0.0981644,"width":0.006150266,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Transferred","depth":25,"bounds":{"left":0.8897939,"top":0.10295291,"width":0.020279255,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.56 kB","depth":23,"bounds":{"left":0.8897939,"top":0.122505985,"width":0.012799202,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Size","depth":23,"bounds":{"left":0.89461434,"top":0.0981644,"width":0.08277926,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Size","depth":25,"bounds":{"left":0.8962766,"top":0.10295291,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.67 kB","depth":23,"bounds":{"left":0.96127,"top":0.122505985,"width":0.014793883,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"0 ms","depth":23,"bounds":{"left":0.97772604,"top":0.0981644,"width":0.021941489,"height":0.01915403},"help_text":"Timeline","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0 ms","depth":26,"bounds":{"left":0.9790558,"top":0.105347164,"width":0.0066489363,"height":0.007980846},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"589 ms","depth":24,"bounds":{"left":0.9793883,"top":0.12330407,"width":0.011303191,"height":0.008778931},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start performance analysis","depth":20,"bounds":{"left":0.54288566,"top":0.98244214,"width":0.007978723,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3 requests","depth":21,"bounds":{"left":0.55452126,"top":0.98523545,"width":0.018450798,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21.99 kB / 18.16 kB transferred","depth":21,"bounds":{"left":0.57995343,"top":0.98523545,"width":0.055518616,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finish: 30.62 s","depth":21,"bounds":{"left":0.64245343,"top":0.98523545,"width":0.025930852,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
9087983999674122723
|
9085277777879295671
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
New Tab
New Tab
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Userpilot | Logged-activity
Userpilot | Logged-activity
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Jiminny
Jiminny
Close tab
Jiminny
Jiminny
Jiminny
Jiminny
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Ask Jiminny Reports
Ask Jiminny Reports
Create
Report name
Prompt Prompt
Prompt
Prompt
Saved search Saved search
Saved search
Saved search
All statuses All statuses
All statuses
All statuses
Clear all
NAME
FREQUENCY
SHARED
EXPIRING
ACTIONS
Exp
Daily
20/04/2027
Monthly Ask J Report
Monthly
Jiminny Mobile SA
30/06/2026
Search One
Daily
Jiminny Mobile SA
30/04/2026
Edit report
Save
1. General
1. General
NAME
Exp
Clear
*
FREQUENCY
Select
Select
*
EXPIRES ON
20 Apr, 2027
*
Share with
TEAM
Select Select
Select
Select
TEAM MEMBER
Select Select
Select
Select
2. Report parameters
2. Report parameters
SAVED SEARCH
Select group one
Select
group one
*
ASK JIMINNY PROMPT
Select Lets test it
Select
Lets test it
*
Report definition saved
Close notification
Clear
Filter URLs
Pause/Resume recording network log
New Request
Search
Request Blocking
All
HTML
CSS
JS
XHR
Fonts
Images
Media
WS
Other
Disable Cache
Disable Cache
No Throttling
Network Settings
Status
Status
Method
Method
Domain
Domain
File
File
Initiator
Initiator
Type
Type
Transferred
Transferred
Size
Size
0 ms
0 ms
200
GET
app.dev.jiminny.com
form-data
xhr
json
7.56 kB
10.67 kB
589 ms
200
POST
app.dev.jiminny.com
aj-reports
xhr
json
3.03 kB
493 B
496 ms
200
GET
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
json
7.57 kB
10.83 kB
406 ms
Status
Status
200
Method
Method
GET
Domain
Domain
app.dev.jiminny.com
File
File
form-data
Initiator
Initiator
xhr
Type
Type
json
Transferred
Transferred
7.56 kB
Size
Size
10.67 kB
0 ms
0 ms
589 ms
Start performance analysis
3 requests
21.99 kB / 18.16 kB transferred
Finish: 30.62 s...
|
54853
|
|
54859
|
1183
|
59
|
2026-04-20T09:21:36.780463+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-20/1776 /Users/lukas/.screenpipe/data/data/2026-04-20/1776676896780_m1.jpg...
|
Firefox
|
Jiminny — Work
|
1
|
app.dev.jiminny.com/ai-reports/manage
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
New Tab
New Tab
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Userpilot | Logged-activity
Userpilot | Logged-activity
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Jiminny
Jiminny
Close tab
Jiminny
Jiminny
Jiminny
Jiminny
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Ask Jiminny Reports
Ask Jiminny Reports
Create
Report name
Prompt Prompt
Prompt
Prompt
Saved search Saved search
Saved search
Saved search
All statuses All statuses
All statuses
All statuses
Clear all
NAME
FREQUENCY
SHARED
EXPIRING
ACTIONS
Exp
Daily
20/04/2027
Monthly Ask J Report
Monthly
Jiminny Mobile SA
30/06/2026
Search One
Daily
Jiminny Mobile SA
30/04/2026
Edit report
Save
1. General
1. General
NAME
Exp
Clear
*
FREQUENCY
Select Weekly
Select
Weekly
*
EXPIRES ON
20 Apr, 2027
*
Share with
TEAM
Select Select
Select
Select
TEAM MEMBER
Select Select
Select
Select
2. Report parameters
2. Report parameters
SAVED SEARCH
Select group one
Select
group one
*
ASK JIMINNY PROMPT
Select Lets test it
Select
Lets test it
*
Clear
Filter URLs
Pause/Resume recording network log
New Request
Search
Request Blocking
All
HTML
CSS
JS
XHR
Fonts
Images
Media
WS
Other
Disable Cache
Disable Cache
No Throttling
Network Settings
Status
Status
Method
Method
Domain
Domain
File
File
Initiator
Initiator
Type
Type
Transferred
Transferred
Size
Size
0 ms
0 ms
200
GET
app.dev.jiminny.com
form-data
xhr
json
7.56 kB
10.67 kB
589 ms
200
POST
app.dev.jiminny.com
aj-reports
xhr
json
3.03 kB
493 B
496 ms
200
GET
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
json
7.57 kB
10.83 kB
406 ms
PUT
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
Status
Status
200
Method
Method
GET
Domain
Domain
app.dev.jiminny.com
File
File
form-data
Initiator
Initiator
xhr
Type
Type
json
Transferred
Transferred
7.56 kB
Size
Size
10.67 kB
0 ms
0 ms
589 ms
Start performance analysis
4 requests
21.99 kB / 18.16 kB transferred
Finish: 34.48 s...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Product Growth Platform | Userpilot","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Growth Platform | Userpilot","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Userpilot | Logged-activity","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Userpilot | Logged-activity","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Ask Jiminny Reports","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ask Jiminny Reports","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"Report name","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Prompt Prompt","depth":10,"value":"Prompt Prompt","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Prompt","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Prompt","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Saved search Saved search","depth":10,"value":"Saved search Saved search","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Saved search","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Saved search","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"All statuses All statuses","depth":10,"value":"All statuses All statuses","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"All statuses","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All statuses","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Clear all","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"NAME","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FREQUENCY","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SHARED","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EXPIRING","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIONS","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Exp","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20/04/2027","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Monthly Ask J Report","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Monthly","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny Mobile SA","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30/06/2026","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search One","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny Mobile SA","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30/04/2026","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Edit report","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Save","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"1. General","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. General","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NAME","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Exp","depth":12,"value":"Exp","help_text":"","placeholder":"Enter name","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Clear","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"*","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FREQUENCY","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Weekly","depth":11,"value":"Select Weekly","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Weekly","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EXPIRES ON","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20 Apr, 2027","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Share with","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TEAM","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Select","depth":11,"value":"Select Select","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TEAM MEMBER","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Select","depth":11,"value":"Select Select","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. Report parameters","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. Report parameters","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SAVED SEARCH","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select group one","depth":11,"value":"Select group one","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"group one","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ASK JIMINNY PROMPT","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Lets test it","depth":11,"value":"Select Lets test it","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lets test it","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Clear","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"Filter URLs","depth":16,"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Pause/Resume recording network log","depth":16,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"New Request","depth":16,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Search","depth":16,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Request Blocking","depth":16,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"All","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"HTML","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"CSS","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"JS","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"XHR","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Fonts","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Images","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Media","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"WS","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Other","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Disable Cache","depth":17,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Disable Cache","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"No Throttling","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Network Settings","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Status","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Method","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Method","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Domain","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Domain","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"File","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"File","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Initiator","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Initiator","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Type","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Transferred","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Transferred","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Size","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Size","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"0 ms","depth":24,"help_text":"Timeline","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0 ms","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"form-data","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.56 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.67 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"589 ms","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POST","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"aj-reports","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3.03 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"493 B","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"496 ms","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7361706f-ffbe-4d3d-a22b-9fab33d05094","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.57 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.83 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"406 ms","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PUT","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7361706f-ffbe-4d3d-a22b-9fab33d05094","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Status","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Method","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Method","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Domain","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Domain","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"File","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"File","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"form-data","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Initiator","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Initiator","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Type","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Transferred","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Transferred","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.56 kB","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Size","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Size","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.67 kB","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"0 ms","depth":23,"help_text":"Timeline","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0 ms","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"589 ms","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start performance analysis","depth":20,"bounds":{"left":0.5694444,"top":0.0,"width":0.016666668,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4 requests","depth":21,"bounds":{"left":0.59375,"top":0.0,"width":0.038541667,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21.99 kB / 18.16 kB transferred","depth":21,"bounds":{"left":0.646875,"top":0.0,"width":0.11597222,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finish: 34.48 s","depth":21,"bounds":{"left":0.77743053,"top":0.0,"width":0.054166667,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
7343803110655130781
|
9085277777099122366
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
New Tab
New Tab
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Userpilot | Logged-activity
Userpilot | Logged-activity
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Jiminny
Jiminny
Close tab
Jiminny
Jiminny
Jiminny
Jiminny
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Ask Jiminny Reports
Ask Jiminny Reports
Create
Report name
Prompt Prompt
Prompt
Prompt
Saved search Saved search
Saved search
Saved search
All statuses All statuses
All statuses
All statuses
Clear all
NAME
FREQUENCY
SHARED
EXPIRING
ACTIONS
Exp
Daily
20/04/2027
Monthly Ask J Report
Monthly
Jiminny Mobile SA
30/06/2026
Search One
Daily
Jiminny Mobile SA
30/04/2026
Edit report
Save
1. General
1. General
NAME
Exp
Clear
*
FREQUENCY
Select Weekly
Select
Weekly
*
EXPIRES ON
20 Apr, 2027
*
Share with
TEAM
Select Select
Select
Select
TEAM MEMBER
Select Select
Select
Select
2. Report parameters
2. Report parameters
SAVED SEARCH
Select group one
Select
group one
*
ASK JIMINNY PROMPT
Select Lets test it
Select
Lets test it
*
Clear
Filter URLs
Pause/Resume recording network log
New Request
Search
Request Blocking
All
HTML
CSS
JS
XHR
Fonts
Images
Media
WS
Other
Disable Cache
Disable Cache
No Throttling
Network Settings
Status
Status
Method
Method
Domain
Domain
File
File
Initiator
Initiator
Type
Type
Transferred
Transferred
Size
Size
0 ms
0 ms
200
GET
app.dev.jiminny.com
form-data
xhr
json
7.56 kB
10.67 kB
589 ms
200
POST
app.dev.jiminny.com
aj-reports
xhr
json
3.03 kB
493 B
496 ms
200
GET
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
json
7.57 kB
10.83 kB
406 ms
PUT
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
Status
Status
200
Method
Method
GET
Domain
Domain
app.dev.jiminny.com
File
File
form-data
Initiator
Initiator
xhr
Type
Type
json
Transferred
Transferred
7.56 kB
Size
Size
10.67 kB
0 ms
0 ms
589 ms
Start performance analysis
4 requests
21.99 kB / 18.16 kB transferred
Finish: 34.48 s...
|
NULL
|
|
54860
|
1184
|
70
|
2026-04-20T09:21:36.704120+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-20/1776 /Users/lukas/.screenpipe/data/data/2026-04-20/1776676896704_m2.jpg...
|
Firefox
|
Jiminny — Work
|
1
|
app.dev.jiminny.com/ai-reports/manage
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
New Tab
New Tab
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Userpilot | Logged-activity
Userpilot | Logged-activity
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Jiminny
Jiminny
Close tab
Jiminny
Jiminny
Jiminny
Jiminny
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Ask Jiminny Reports
Ask Jiminny Reports
Create
Report name
Prompt Prompt
Prompt
Prompt
Saved search Saved search
Saved search
Saved search
All statuses All statuses
All statuses
All statuses
Clear all
NAME
FREQUENCY
SHARED
EXPIRING
ACTIONS
Exp
Daily
20/04/2027
Monthly Ask J Report
Monthly
Jiminny Mobile SA
30/06/2026
Search One
Daily
Jiminny Mobile SA
30/04/2026
Edit report
Save
1. General
1. General
NAME
Exp
Clear
*
FREQUENCY
Select Weekly
Select
Weekly
*
EXPIRES ON
20 Apr, 2027
*
Share with
TEAM
Select Select
Select
Select
TEAM MEMBER
Select Select
Select
Select
2. Report parameters
2. Report parameters
SAVED SEARCH
Select group one
Select
group one
*
ASK JIMINNY PROMPT
Select Lets test it
Select
Lets test it
*
Clear
Filter URLs
Pause/Resume recording network log
New Request
Search
Request Blocking
All
HTML
CSS
JS
XHR
Fonts
Images
Media
WS
Other
Disable Cache
Disable Cache
No Throttling
Network Settings
Status
Status
Method
Method
Domain
Domain
File
File
Initiator
Initiator
Type
Type
Transferred
Transferred
Size
Size
0 ms
0 ms
200
GET
app.dev.jiminny.com
form-data
xhr
json
7.56 kB
10.67 kB
589 ms
200
POST
app.dev.jiminny.com
aj-reports
xhr
json
3.03 kB
493 B
496 ms
200
GET
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
json
7.57 kB
10.83 kB
406 ms
PUT
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
Status
Status
200
Method
Method
GET
Domain
Domain
app.dev.jiminny.com
File
File
form-data
Initiator
Initiator
xhr
Type
Type
json
Transferred
Transferred
7.56 kB
Size
Size
10.67 kB
0 ms
0 ms
589 ms
Start performance analysis
4 requests
21.99 kB / 18.16 kB transferred
Finish: 34.48 s...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0018284575,"top":0.0518755,"width":0.07596409,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.09497207,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.10614525,"width":0.15774602,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"bounds":{"left":0.0,"top":0.12769353,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.13886672,"width":0.09524601,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.16041501,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.17158818,"width":0.19963431,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19313647,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.20430966,"width":0.15525267,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":4,"bounds":{"left":0.0,"top":0.22585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.23703113,"width":0.06981383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":4,"bounds":{"left":0.0,"top":0.2585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.2697526,"width":0.10688165,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.29130086,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.30247405,"width":0.12915559,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.32402235,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.013297873,"top":0.33519554,"width":0.014960106,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Product Growth Platform | Userpilot","depth":4,"bounds":{"left":0.0,"top":0.3567438,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Growth Platform | Userpilot","depth":5,"bounds":{"left":0.013297873,"top":0.367917,"width":0.06200133,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Userpilot | Logged-activity","depth":4,"bounds":{"left":0.0,"top":0.38946527,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Userpilot | Logged-activity","depth":5,"bounds":{"left":0.013297873,"top":0.40063846,"width":0.04637633,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.42218676,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.43335995,"width":0.2052859,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.45490822,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.4660814,"width":0.039228722,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.0,"top":0.48762968,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.013297873,"top":0.49880287,"width":0.042719416,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.5203512,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.53152436,"width":0.2052859,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.55307263,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.5642458,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.5602554,"width":0.007978723,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.5857941,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.5969673,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.61851555,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.62968874,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.6528332,"width":0.07413564,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Ask Jiminny Reports","depth":10,"bounds":{"left":0.10887633,"top":0.06943336,"width":0.06000665,"height":0.019553073},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ask Jiminny Reports","depth":11,"bounds":{"left":0.10887633,"top":0.06943336,"width":0.06000665,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create","depth":10,"bounds":{"left":0.5103058,"top":0.06464485,"width":0.023271276,"height":0.028731046},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"Report name","depth":11,"bounds":{"left":0.12134308,"top":0.10933759,"width":0.058011968,"height":0.019952115},"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Prompt Prompt","depth":10,"bounds":{"left":0.19930187,"top":0.10933759,"width":0.0731383,"height":0.019952115},"value":"Prompt Prompt","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Prompt","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Prompt","depth":12,"bounds":{"left":0.19930187,"top":0.11292897,"width":0.01462766,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Saved search Saved search","depth":10,"bounds":{"left":0.28041887,"top":0.10933759,"width":0.0731383,"height":0.019952115},"value":"Saved search Saved search","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Saved search","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Saved search","depth":12,"bounds":{"left":0.28041887,"top":0.11292897,"width":0.025099734,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"All statuses All statuses","depth":10,"bounds":{"left":0.3615359,"top":0.10933759,"width":0.059840426,"height":0.019952115},"value":"All statuses All statuses","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"All statuses","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All statuses","depth":12,"bounds":{"left":0.3615359,"top":0.11292897,"width":0.022273935,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Clear all","depth":10,"bounds":{"left":0.42503324,"top":0.112529926,"width":0.024268618,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"NAME","depth":12,"bounds":{"left":0.10854388,"top":0.16679968,"width":0.012965426,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FREQUENCY","depth":12,"bounds":{"left":0.2521609,"top":0.16679968,"width":0.026097074,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SHARED","depth":12,"bounds":{"left":0.32396942,"top":0.16679968,"width":0.017453458,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EXPIRING","depth":12,"bounds":{"left":0.3956117,"top":0.16679968,"width":0.02044548,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIONS","depth":12,"bounds":{"left":0.46742022,"top":0.16679968,"width":0.019115692,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Exp","depth":14,"bounds":{"left":0.10854388,"top":0.207502,"width":0.00731383,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily","depth":14,"bounds":{"left":0.2521609,"top":0.207502,"width":0.010139627,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20/04/2027","depth":14,"bounds":{"left":0.3956117,"top":0.207502,"width":0.024102394,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Monthly Ask J Report","depth":14,"bounds":{"left":0.10854388,"top":0.2462091,"width":0.042220745,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Monthly","depth":14,"bounds":{"left":0.2521609,"top":0.2462091,"width":0.01662234,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny Mobile SA","depth":15,"bounds":{"left":0.33111703,"top":0.23902634,"width":0.015957447,"height":0.04309657},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30/06/2026","depth":14,"bounds":{"left":0.3956117,"top":0.2462091,"width":0.024102394,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search One","depth":14,"bounds":{"left":0.10854388,"top":0.28451717,"width":0.022606382,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily","depth":14,"bounds":{"left":0.2521609,"top":0.28451717,"width":0.010139627,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny Mobile SA","depth":15,"bounds":{"left":0.33111703,"top":0.2773344,"width":0.015957447,"height":0.04309657},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30/04/2026","depth":14,"bounds":{"left":0.3956117,"top":0.28451717,"width":0.024102394,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Edit report","depth":13,"bounds":{"left":0.34208778,"top":0.06943336,"width":0.032247342,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Save","depth":12,"bounds":{"left":0.5024933,"top":0.0650439,"width":0.018118352,"height":0.02793296},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXHeading","text":"1. General","depth":11,"bounds":{"left":0.34208778,"top":0.12609737,"width":0.19414894,"height":0.032721467},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. General","depth":12,"bounds":{"left":0.34208778,"top":0.13248204,"width":0.024601065,"height":0.01556265},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NAME","depth":13,"bounds":{"left":0.3464096,"top":0.16799681,"width":0.009973404,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Exp","depth":12,"bounds":{"left":0.3464096,"top":0.17797287,"width":0.1775266,"height":0.019952115},"value":"Exp","help_text":"","placeholder":"Enter name","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Clear","depth":12,"bounds":{"left":0.52393615,"top":0.1783719,"width":0.007978723,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"*","depth":12,"bounds":{"left":0.53125,"top":0.16241021,"width":0.0026595744,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FREQUENCY","depth":13,"bounds":{"left":0.3464096,"top":0.22306465,"width":0.020279255,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Weekly","depth":11,"bounds":{"left":0.3464096,"top":0.2330407,"width":0.09075798,"height":0.019952115},"value":"Select Weekly","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Weekly","depth":13,"bounds":{"left":0.3464096,"top":0.23663208,"width":0.014793883,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":12,"bounds":{"left":0.4325133,"top":0.21747805,"width":0.0026595744,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EXPIRES ON","depth":15,"bounds":{"left":0.44514626,"top":0.22306465,"width":0.019281914,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20 Apr, 2027","depth":15,"bounds":{"left":0.44514626,"top":0.2386273,"width":0.024933511,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":14,"bounds":{"left":0.53125,"top":0.21747805,"width":0.0026595744,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Share with","depth":12,"bounds":{"left":0.34208778,"top":0.27094972,"width":0.022107713,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TEAM","depth":13,"bounds":{"left":0.3464096,"top":0.2980846,"width":0.009474734,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Select","depth":11,"bounds":{"left":0.3464096,"top":0.30806065,"width":0.09075798,"height":0.019952115},"value":"Select Select","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select","depth":13,"bounds":{"left":0.3464096,"top":0.31165203,"width":0.011801862,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TEAM MEMBER","depth":13,"bounds":{"left":0.44514626,"top":0.2980846,"width":0.024601065,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Select","depth":11,"bounds":{"left":0.44514626,"top":0.30806065,"width":0.09075798,"height":0.019952115},"value":"Select Select","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select","depth":13,"bounds":{"left":0.44514626,"top":0.31165203,"width":0.011801862,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. Report parameters","depth":11,"bounds":{"left":0.34208778,"top":0.34477255,"width":0.19414894,"height":0.032721467},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. Report parameters","depth":12,"bounds":{"left":0.34208778,"top":0.35115722,"width":0.05119681,"height":0.01556265},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SAVED SEARCH","depth":13,"bounds":{"left":0.3464096,"top":0.386672,"width":0.02443484,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select group one","depth":11,"bounds":{"left":0.3464096,"top":0.39664805,"width":0.09075798,"height":0.019952115},"value":"Select group one","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"group one","depth":13,"bounds":{"left":0.3464096,"top":0.40023944,"width":0.019448139,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":12,"bounds":{"left":0.4325133,"top":0.3810854,"width":0.0026595744,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ASK JIMINNY PROMPT","depth":13,"bounds":{"left":0.44514626,"top":0.386672,"width":0.035904255,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Lets test it","depth":11,"bounds":{"left":0.44514626,"top":0.39664805,"width":0.09075798,"height":0.019952115},"value":"Select Lets test it","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lets test it","depth":13,"bounds":{"left":0.44514626,"top":0.40023944,"width":0.020279255,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":12,"bounds":{"left":0.53125,"top":0.3810854,"width":0.0026595744,"height":0.019553073},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Clear","depth":16,"bounds":{"left":0.54288566,"top":0.07821229,"width":0.008643617,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"Filter URLs","depth":16,"bounds":{"left":0.5531915,"top":0.07581804,"width":0.18517287,"height":0.0207502},"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Pause/Resume recording network log","depth":16,"bounds":{"left":0.75199467,"top":0.077813245,"width":0.008643617,"height":0.016759777},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"New Request","depth":16,"bounds":{"left":0.7613032,"top":0.07821229,"width":0.008643617,"height":0.015961692},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Search","depth":16,"bounds":{"left":0.7706117,"top":0.07821229,"width":0.008643617,"height":0.015961692},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Request Blocking","depth":16,"bounds":{"left":0.7799202,"top":0.07821229,"width":0.008643617,"height":0.015961692},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"All","depth":17,"bounds":{"left":0.7925532,"top":0.07861133,"width":0.00831117,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"HTML","depth":17,"bounds":{"left":0.8015292,"top":0.07861133,"width":0.014295213,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"CSS","depth":17,"bounds":{"left":0.81648934,"top":0.07861133,"width":0.011469414,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"JS","depth":17,"bounds":{"left":0.82862365,"top":0.07861133,"width":0.00831117,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"XHR","depth":17,"bounds":{"left":0.83759975,"top":0.07861133,"width":0.011635638,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Fonts","depth":17,"bounds":{"left":0.84990025,"top":0.07861133,"width":0.013630319,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Images","depth":17,"bounds":{"left":0.86419547,"top":0.07861133,"width":0.01662234,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Media","depth":17,"bounds":{"left":0.8814827,"top":0.07861133,"width":0.014461436,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"WS","depth":17,"bounds":{"left":0.89660907,"top":0.07861133,"width":0.009973404,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Other","depth":17,"bounds":{"left":0.90724736,"top":0.07861133,"width":0.013796543,"height":0.01556265},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Disable Cache","depth":17,"bounds":{"left":0.92669547,"top":0.080207504,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Disable Cache","depth":17,"bounds":{"left":0.93234706,"top":0.08100559,"width":0.024933511,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"No Throttling","depth":16,"bounds":{"left":0.9609375,"top":0.07940942,"width":0.027094414,"height":0.01396648},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Network Settings","depth":16,"bounds":{"left":0.9896942,"top":0.07821229,"width":0.008643617,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Status","depth":24,"bounds":{"left":0.5415558,"top":0.0981644,"width":0.027593086,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status","depth":26,"bounds":{"left":0.5432181,"top":0.10295291,"width":0.011136968,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Method","depth":24,"bounds":{"left":0.5694814,"top":0.0981644,"width":0.027260639,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Method","depth":26,"bounds":{"left":0.5711436,"top":0.10295291,"width":0.013297873,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Domain","depth":24,"bounds":{"left":0.59707445,"top":0.0981644,"width":0.06981383,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Domain","depth":26,"bounds":{"left":0.5987367,"top":0.10295291,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"File","depth":24,"bounds":{"left":0.6672208,"top":0.0981644,"width":0.1377992,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"File","depth":26,"bounds":{"left":0.66888297,"top":0.10295291,"width":0.006150266,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Initiator","depth":24,"bounds":{"left":0.8053524,"top":0.0981644,"width":0.054853722,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Initiator","depth":26,"bounds":{"left":0.80701464,"top":0.10295291,"width":0.013297873,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Type","depth":24,"bounds":{"left":0.86053854,"top":0.0981644,"width":0.027260639,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":26,"bounds":{"left":0.8622008,"top":0.10295291,"width":0.008477394,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Transferred","depth":24,"bounds":{"left":0.8881317,"top":0.0981644,"width":0.006150266,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Transferred","depth":26,"bounds":{"left":0.8897939,"top":0.10295291,"width":0.020279255,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Size","depth":24,"bounds":{"left":0.89461434,"top":0.0981644,"width":0.08277926,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Size","depth":26,"bounds":{"left":0.8962766,"top":0.10295291,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"0 ms","depth":24,"bounds":{"left":0.97772604,"top":0.0981644,"width":0.021941489,"height":0.01915403},"help_text":"Timeline","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0 ms","depth":27,"bounds":{"left":0.9790558,"top":0.105347164,"width":0.0066489363,"height":0.007980846},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"bounds":{"left":0.54388297,"top":0.12290503,"width":0.006482713,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":24,"bounds":{"left":0.5711436,"top":0.122505985,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"bounds":{"left":0.6037234,"top":0.122505985,"width":0.03507314,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"form-data","depth":25,"bounds":{"left":0.66888297,"top":0.122505985,"width":0.017453458,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"bounds":{"left":0.80701464,"top":0.122505985,"width":0.005485372,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"bounds":{"left":0.8622008,"top":0.122505985,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.56 kB","depth":24,"bounds":{"left":0.8897939,"top":0.122505985,"width":0.012799202,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.67 kB","depth":24,"bounds":{"left":0.96127,"top":0.122505985,"width":0.014793883,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"589 ms","depth":25,"bounds":{"left":0.9793883,"top":0.12330407,"width":0.011303191,"height":0.008778931},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"bounds":{"left":0.54388297,"top":0.14205906,"width":0.006482713,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POST","depth":24,"bounds":{"left":0.5711436,"top":0.14166002,"width":0.009807181,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"bounds":{"left":0.6037234,"top":0.14166002,"width":0.03507314,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"aj-reports","depth":25,"bounds":{"left":0.66888297,"top":0.14166002,"width":0.017287234,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"bounds":{"left":0.80701464,"top":0.14166002,"width":0.005485372,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"bounds":{"left":0.8622008,"top":0.14166002,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3.03 kB","depth":24,"bounds":{"left":0.8897939,"top":0.14166002,"width":0.013297873,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"493 B","depth":24,"bounds":{"left":0.9655917,"top":0.14166002,"width":0.010472074,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"496 ms","depth":25,"bounds":{"left":0.9878657,"top":0.1424581,"width":0.011136968,"height":0.008778931},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"bounds":{"left":0.54388297,"top":0.16121309,"width":0.006482713,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":24,"bounds":{"left":0.5711436,"top":0.16081405,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"bounds":{"left":0.6037234,"top":0.16081405,"width":0.03507314,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7361706f-ffbe-4d3d-a22b-9fab33d05094","depth":25,"bounds":{"left":0.66888297,"top":0.16081405,"width":0.07480053,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"bounds":{"left":0.80701464,"top":0.16081405,"width":0.005485372,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"bounds":{"left":0.8622008,"top":0.16081405,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.57 kB","depth":24,"bounds":{"left":0.8897939,"top":0.16081405,"width":0.012632979,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.83 kB","depth":24,"bounds":{"left":0.96110374,"top":0.16081405,"width":0.014960106,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"406 ms","depth":25,"bounds":{"left":0.98952794,"top":0.16161214,"width":0.010472059,"height":0.008778931},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PUT","depth":24,"bounds":{"left":0.5711436,"top":0.17996807,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"bounds":{"left":0.5984042,"top":0.17996807,"width":0.03507314,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7361706f-ffbe-4d3d-a22b-9fab33d05094","depth":25,"bounds":{"left":0.66888297,"top":0.17996807,"width":0.07480053,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"bounds":{"left":0.80701464,"top":0.17996807,"width":0.005485372,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Status","depth":23,"bounds":{"left":0.5415558,"top":0.0981644,"width":0.027593086,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status","depth":25,"bounds":{"left":0.5432181,"top":0.10295291,"width":0.011136968,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":23,"bounds":{"left":0.54388297,"top":0.12290503,"width":0.006482713,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Method","depth":23,"bounds":{"left":0.5694814,"top":0.0981644,"width":0.027260639,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Method","depth":25,"bounds":{"left":0.5711436,"top":0.10295291,"width":0.013297873,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":23,"bounds":{"left":0.5711436,"top":0.122505985,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Domain","depth":23,"bounds":{"left":0.59707445,"top":0.0981644,"width":0.06981383,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Domain","depth":25,"bounds":{"left":0.5987367,"top":0.10295291,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":23,"bounds":{"left":0.6037234,"top":0.122505985,"width":0.03507314,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"File","depth":23,"bounds":{"left":0.6672208,"top":0.0981644,"width":0.1377992,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"File","depth":25,"bounds":{"left":0.66888297,"top":0.10295291,"width":0.006150266,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"form-data","depth":24,"bounds":{"left":0.66888297,"top":0.122505985,"width":0.017453458,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Initiator","depth":23,"bounds":{"left":0.8053524,"top":0.0981644,"width":0.054853722,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Initiator","depth":25,"bounds":{"left":0.80701464,"top":0.10295291,"width":0.013297873,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":23,"bounds":{"left":0.80701464,"top":0.122505985,"width":0.005485372,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Type","depth":23,"bounds":{"left":0.86053854,"top":0.0981644,"width":0.027260639,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":25,"bounds":{"left":0.8622008,"top":0.10295291,"width":0.008477394,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":23,"bounds":{"left":0.8622008,"top":0.122505985,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Transferred","depth":23,"bounds":{"left":0.8881317,"top":0.0981644,"width":0.006150266,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Transferred","depth":25,"bounds":{"left":0.8897939,"top":0.10295291,"width":0.020279255,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.56 kB","depth":23,"bounds":{"left":0.8897939,"top":0.122505985,"width":0.012799202,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Size","depth":23,"bounds":{"left":0.89461434,"top":0.0981644,"width":0.08277926,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Size","depth":25,"bounds":{"left":0.8962766,"top":0.10295291,"width":0.00731383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.67 kB","depth":23,"bounds":{"left":0.96127,"top":0.122505985,"width":0.014793883,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"0 ms","depth":23,"bounds":{"left":0.97772604,"top":0.0981644,"width":0.021941489,"height":0.01915403},"help_text":"Timeline","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0 ms","depth":26,"bounds":{"left":0.9790558,"top":0.105347164,"width":0.0066489363,"height":0.007980846},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"589 ms","depth":24,"bounds":{"left":0.9793883,"top":0.12330407,"width":0.011303191,"height":0.008778931},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start performance analysis","depth":20,"bounds":{"left":0.54288566,"top":0.98244214,"width":0.007978723,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4 requests","depth":21,"bounds":{"left":0.55452126,"top":0.98523545,"width":0.018450798,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21.99 kB / 18.16 kB transferred","depth":21,"bounds":{"left":0.57995343,"top":0.98523545,"width":0.055518616,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finish: 34.48 s","depth":21,"bounds":{"left":0.64245343,"top":0.98523545,"width":0.025930852,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
7343803110655130781
|
9085277777099122366
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
New Tab
New Tab
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Userpilot | Logged-activity
Userpilot | Logged-activity
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Jiminny
Jiminny
Close tab
Jiminny
Jiminny
Jiminny
Jiminny
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Ask Jiminny Reports
Ask Jiminny Reports
Create
Report name
Prompt Prompt
Prompt
Prompt
Saved search Saved search
Saved search
Saved search
All statuses All statuses
All statuses
All statuses
Clear all
NAME
FREQUENCY
SHARED
EXPIRING
ACTIONS
Exp
Daily
20/04/2027
Monthly Ask J Report
Monthly
Jiminny Mobile SA
30/06/2026
Search One
Daily
Jiminny Mobile SA
30/04/2026
Edit report
Save
1. General
1. General
NAME
Exp
Clear
*
FREQUENCY
Select Weekly
Select
Weekly
*
EXPIRES ON
20 Apr, 2027
*
Share with
TEAM
Select Select
Select
Select
TEAM MEMBER
Select Select
Select
Select
2. Report parameters
2. Report parameters
SAVED SEARCH
Select group one
Select
group one
*
ASK JIMINNY PROMPT
Select Lets test it
Select
Lets test it
*
Clear
Filter URLs
Pause/Resume recording network log
New Request
Search
Request Blocking
All
HTML
CSS
JS
XHR
Fonts
Images
Media
WS
Other
Disable Cache
Disable Cache
No Throttling
Network Settings
Status
Status
Method
Method
Domain
Domain
File
File
Initiator
Initiator
Type
Type
Transferred
Transferred
Size
Size
0 ms
0 ms
200
GET
app.dev.jiminny.com
form-data
xhr
json
7.56 kB
10.67 kB
589 ms
200
POST
app.dev.jiminny.com
aj-reports
xhr
json
3.03 kB
493 B
496 ms
200
GET
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
json
7.57 kB
10.83 kB
406 ms
PUT
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
Status
Status
200
Method
Method
GET
Domain
Domain
app.dev.jiminny.com
File
File
form-data
Initiator
Initiator
xhr
Type
Type
json
Transferred
Transferred
7.56 kB
Size
Size
10.67 kB
0 ms
0 ms
589 ms
Start performance analysis
4 requests
21.99 kB / 18.16 kB transferred
Finish: 34.48 s...
|
NULL
|
|
54857
|
1183
|
58
|
2026-04-20T09:21:35.586836+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-20/1776 /Users/lukas/.screenpipe/data/data/2026-04-20/1776676895586_m1.jpg...
|
Firefox
|
Jiminny — Work
|
1
|
app.dev.jiminny.com/ai-reports/manage
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
New Tab
New Tab
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Userpilot | Logged-activity
Userpilot | Logged-activity
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Jiminny
Jiminny
Close tab
Jiminny
Jiminny
Jiminny
Jiminny
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Ask Jiminny Reports
Ask Jiminny Reports
Create
Report name
Prompt Prompt
Prompt
Prompt
Saved search Saved search
Saved search
Saved search
All statuses All statuses
All statuses
All statuses
Clear all
NAME
FREQUENCY
SHARED
EXPIRING
ACTIONS
Exp
Daily
20/04/2027
Monthly Ask J Report
Monthly
Jiminny Mobile SA
30/06/2026
Search One
Daily
Jiminny Mobile SA
30/04/2026
Edit report
Save
1. General
1. General
NAME
Exp
Clear
*
FREQUENCY
Select Weekly
Select
Weekly
*
EXPIRES ON
20 Apr, 2027
*
Share with
TEAM
Select Select
Select
Select
TEAM MEMBER
Select Select
Select
Select
2. Report parameters
2. Report parameters
SAVED SEARCH
Select group one
Select
group one
*
ASK JIMINNY PROMPT
Select Lets test it
Select
Lets test it
*
Clear
Filter URLs
Pause/Resume recording network log
New Request
Search
Request Blocking
All
HTML
CSS
JS
XHR
Fonts
Images
Media
WS
Other
Disable Cache
Disable Cache
No Throttling
Network Settings
Status
Status
Method
Method
Domain
Domain
File
File
Initiator
Initiator
Type
Type
Transferred
Transferred
Size
Size
0 ms
0 ms
200
GET
app.dev.jiminny.com
form-data
xhr
json
7.56 kB
10.67 kB
589 ms
200
POST
app.dev.jiminny.com
aj-reports
xhr
json
3.03 kB
493 B
496 ms
200
GET
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
json
7.57 kB
10.83 kB
406 ms
Status
Status
200
Method
Method
GET
Domain
Domain
app.dev.jiminny.com
File
File
form-data
Initiator
Initiator
xhr
Type
Type
json
Transferred
Transferred
7.56 kB
Size
Size
10.67 kB
0 ms
0 ms
589 ms
Start performance analysis
3 requests
21.99 kB / 18.16 kB transferred
Finish: 30.62 s...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Product Growth Platform | Userpilot","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Growth Platform | Userpilot","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Userpilot | Logged-activity","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Userpilot | Logged-activity","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Ask Jiminny Reports","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ask Jiminny Reports","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"Report name","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Prompt Prompt","depth":10,"value":"Prompt Prompt","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Prompt","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Prompt","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Saved search Saved search","depth":10,"value":"Saved search Saved search","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Saved search","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Saved search","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"All statuses All statuses","depth":10,"value":"All statuses All statuses","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"All statuses","depth":11,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All statuses","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Clear all","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"NAME","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FREQUENCY","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SHARED","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EXPIRING","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIONS","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Exp","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20/04/2027","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Monthly Ask J Report","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Monthly","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny Mobile SA","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30/06/2026","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search One","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny Mobile SA","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30/04/2026","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Edit report","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Save","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"1. General","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. General","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NAME","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Exp","depth":12,"value":"Exp","help_text":"","placeholder":"Enter name","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Clear","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"*","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FREQUENCY","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Weekly","depth":11,"value":"Select Weekly","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Weekly","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"EXPIRES ON","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"20 Apr, 2027","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Share with","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TEAM","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Select","depth":11,"value":"Select Select","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TEAM MEMBER","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Select","depth":11,"value":"Select Select","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Select","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. Report parameters","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. Report parameters","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SAVED SEARCH","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select group one","depth":11,"value":"Select group one","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"group one","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ASK JIMINNY PROMPT","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select Lets test it","depth":11,"value":"Select Lets test it","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lets test it","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Clear","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"Filter URLs","depth":16,"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Pause/Resume recording network log","depth":16,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"New Request","depth":16,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Search","depth":16,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Request Blocking","depth":16,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"All","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"HTML","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"CSS","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"JS","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"XHR","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Fonts","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Images","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Media","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"WS","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Other","depth":17,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Disable Cache","depth":17,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Disable Cache","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"No Throttling","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Network Settings","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Status","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Method","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Method","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Domain","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Domain","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"File","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"File","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Initiator","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Initiator","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Type","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Transferred","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Transferred","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Size","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Size","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"0 ms","depth":24,"help_text":"Timeline","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0 ms","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"form-data","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.56 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.67 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"589 ms","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POST","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"aj-reports","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3.03 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"493 B","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"496 ms","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7361706f-ffbe-4d3d-a22b-9fab33d05094","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.57 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.83 kB","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"406 ms","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Status","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Status","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"200","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Method","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Method","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"GET","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Domain","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Domain","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"File","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"File","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"form-data","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Initiator","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Initiator","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"xhr","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Type","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Transferred","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Transferred","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7.56 kB","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Size","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Size","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10.67 kB","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"0 ms","depth":23,"help_text":"Timeline","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0 ms","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"589 ms","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start performance analysis","depth":20,"bounds":{"left":0.5694444,"top":0.0,"width":0.016666668,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3 requests","depth":21,"bounds":{"left":0.59375,"top":0.0,"width":0.038541667,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21.99 kB / 18.16 kB transferred","depth":21,"bounds":{"left":0.646875,"top":0.0,"width":0.11597222,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finish: 30.62 s","depth":21,"bounds":{"left":0.77743053,"top":0.0,"width":0.054166667,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-4434378097077835084
|
9085277776813942463
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
JY-20553 | Improve crm-sync delays by yalokin-jiminny · Pull Request #11976 · jiminny/app
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
New Tab
New Tab
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Userpilot | Logged-activity
Userpilot | Logged-activity
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Pipelines - jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Feed — jiminny — Sentry
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
fix(security): composer dependency updates – 2026-04-15 by github-actions[bot] · Pull Request #11970 · jiminny/app
Jiminny
Jiminny
Close tab
Jiminny
Jiminny
Jiminny
Jiminny
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Ask Jiminny Reports
Ask Jiminny Reports
Create
Report name
Prompt Prompt
Prompt
Prompt
Saved search Saved search
Saved search
Saved search
All statuses All statuses
All statuses
All statuses
Clear all
NAME
FREQUENCY
SHARED
EXPIRING
ACTIONS
Exp
Daily
20/04/2027
Monthly Ask J Report
Monthly
Jiminny Mobile SA
30/06/2026
Search One
Daily
Jiminny Mobile SA
30/04/2026
Edit report
Save
1. General
1. General
NAME
Exp
Clear
*
FREQUENCY
Select Weekly
Select
Weekly
*
EXPIRES ON
20 Apr, 2027
*
Share with
TEAM
Select Select
Select
Select
TEAM MEMBER
Select Select
Select
Select
2. Report parameters
2. Report parameters
SAVED SEARCH
Select group one
Select
group one
*
ASK JIMINNY PROMPT
Select Lets test it
Select
Lets test it
*
Clear
Filter URLs
Pause/Resume recording network log
New Request
Search
Request Blocking
All
HTML
CSS
JS
XHR
Fonts
Images
Media
WS
Other
Disable Cache
Disable Cache
No Throttling
Network Settings
Status
Status
Method
Method
Domain
Domain
File
File
Initiator
Initiator
Type
Type
Transferred
Transferred
Size
Size
0 ms
0 ms
200
GET
app.dev.jiminny.com
form-data
xhr
json
7.56 kB
10.67 kB
589 ms
200
POST
app.dev.jiminny.com
aj-reports
xhr
json
3.03 kB
493 B
496 ms
200
GET
app.dev.jiminny.com
7361706f-ffbe-4d3d-a22b-9fab33d05094
xhr
json
7.57 kB
10.83 kB
406 ms
Status
Status
200
Method
Method
GET
Domain
Domain
app.dev.jiminny.com
File
File
form-data
Initiator
Initiator
xhr
Type
Type
json
Transferred
Transferred
7.56 kB
Size
Size
10.67 kB
0 ms
0 ms
589 ms
Start performance analysis
3 requests
21.99 kB / 18.16 kB transferred
Finish: 30.62 s...
|
54854
|
|
41415
|
880
|
9
|
2026-04-17T06:13:02.631754+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-17/1776 /Users/lukas/.screenpipe/data/data/2026-04-17/1776406382631_m2.jpg...
|
Firefox
|
CloudWatch | us-east-2 — Work
|
1
|
us-east-2.console.aws.amazon.com/cloudwatch/home?r us-east-2.console.aws.amazon.com/cloudwatch/home?region=us-east-2#logsV2:logs-insights$3FqueryDetail$3D~(end~0~start~-3600~timeType~'RELATIVE~tz~'UTC~unit~'seconds~editorString~'fields*20*40timestamp*2c*20*40message*2c*20*40logStream*2c*20*40log*0a*7c*20filter*20*40message*20like*20*2fXXXXX*2f*20*0a*7c*20filter*20*40message*20not*20like*20*2fAnalytic*2f*20*7c*20filter*20*40message*20not*20like*20*2fTranscript*2f*0a*7c*20filter*20*40message*20not*20like*20*2fWebhook*2f*20*7c*20filter*20*40message*20not*20like*20*2fMeetingBot*2f*20*0a*7c*20limit*2010000~queryId~'0551e814-f51a-4339-8372-80d7ba4cef27~source~(~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-analytics~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-app~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-audio~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-calendar~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-conferences~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-crm-sync~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-default~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-delayed~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-dialers~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-dialers-fifo~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-download~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-emails~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-meeting-bot~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-nudges~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-1~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-2~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-3~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-4~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-5~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-delayed~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-softphone~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-video~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-video-app~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aphp~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aphp-app)~lang~'CWLI~logClass~'STANDARD~queryBy~'logGroupName)...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom
Custom
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Logs (-)
Logs
(
-
)
Patterns (-)
Patterns
(
-
)
Visualization
Visualization
Logs (-)
Logs (-)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
No results
Run a query to see related events
Close saved and sample queries drawer
Queries
Queries
Saved queries
Saved queries
Learn more about saved queries (opens in a new tab)
Learn more
Filter by query name
Create query
CleanDB (14)
CleanDB (14)
CRM (14)
CRM (14)
Dialers (11)
Dialers (11)
Integrations (2)
Integrations (2)
LiveCoach (5)
LiveCoach (5)
Meetings (4)
Meetings (4)
Notetaker (4)
Notetaker (4)
Nudge (2)
Nudge (2)
Ogi (5)
Ogi (5)
Processing team (6)
Processing team (6)
Prophet (3)
Prophet (3)
RDS (4)
RDS (4)
Recall (6)
Recall (6)
Reports (4)
Reports (4)
Tomov (4)
Tomov (4)
_General
-
CWLI
Use as parameterized query
_Planhat Errors
-
CWLI
Use as parameterized query
Berdock
-
CWLI
Use as parameterized query
Command Memory Usage
-
CWLI
Use as parameterized query
Conference Failure
-
CWLI
Use as parameterized query
Customer API response time
-
CWLI
Use as parameterized query
DB Errors
-
CWLI
Use as parameterized query
Duplicated track event
-
CWLI
Use as parameterized query
Emo(Activity Log)
-
CWLI
Use as parameterized query
Encoding steps logs
-
CWLI
Use as parameterized query
Fatal Errors
-
CWLI
Use as parameterized query
Find in message
-
CWLI
Use as parameterized query
find no match with user locales
-
CWLI
Use as parameterized query
For Activity UUID
-
CWLI
Use as parameterized query
Job timeout
-
CWLI
Use as parameterized query
Kiosk
-
CWLI
Use as parameterized query
LiveCoachedActivities
-
CWLI
Use as parameterized query
Login Page Visits
-
CWLI
Use as parameterized query
Logins without valid user
-
CWLI
Use as parameterized query
Logouts
-
CWLI
Use as parameterized query
Meeting Bot Delays
-
CWLI
Use as parameterized query
MeetingOwner
-
CWLI
Use as parameterized query
Parse Nginx Access Log
-
CWLI
Use as parameterized query
Recall error - rate limits or not enough bots
-
CWLI
Use as parameterized query
Search by activity
-
CWLI
Use as parameterized query
Slow Http Requests
-
CWLI
Use as parameterized query
Slow PHP log
-
CWLI
Use as parameterized query
Slow RDS queries
-
CWLI
Use as parameterized query
test
-
CWLI
Use as parameterized query
Sample queries
Sample queries
Learn more about sample queries (opens in a new tab)
Learn more
Common queries
Common queries
Lambda
Lambda
VPC Flow Logs
VPC Flow Logs
CloudTrail
CloudTrail
NetworkFirewall
NetworkFirewall
Route53
Route53
AWS AppSync
AWS AppSync
NAT Gateway
NAT Gateway
IoT
IoT
Elemental MediaPackage V2 Access Logs
Elemental MediaPackage V2 Access Logs
SES Mail Manager
SES Mail Manager
Amazon Q Business Conversation Log
Amazon Q Business Conversation Log
CloudShell
CloudShell
Feedback
Feedback
©
2026
,
Amazon Web Services, Inc.
or its affiliates.
Privacy
Privacy
Terms
Terms
Cookie preferences...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.045138888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.05486111,"width":0.11875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"bounds":{"left":0.0,"top":0.07361111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"bounds":{"left":0.015625,"top":0.083333336,"width":0.11171875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.10208333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.015625,"top":0.11180556,"width":0.017578125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":4,"bounds":{"left":0.0,"top":0.13055556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":5,"bounds":{"left":0.015625,"top":0.14027777,"width":0.53398436,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.15902779,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.16875,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.16527778,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.1875,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.19722222,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | eu-west-1","depth":4,"bounds":{"left":0.0,"top":0.21597221,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | eu-west-1","depth":5,"bounds":{"left":0.015625,"top":0.22569445,"width":0.0875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.24583334,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"AWS Console Home","depth":13,"bounds":{"left":0.09375,"top":0.047916666,"width":0.025390625,"height":0.033333335},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to Main Content","depth":13,"bounds":{"left":0.09335937,"top":0.047222223,"width":0.0015625,"height":0.0013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to Main Content","depth":14,"bounds":{"left":0.09414063,"top":0.047916666,"width":0.01953125,"height":0.045138888},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon Q","depth":14,"bounds":{"left":0.11953125,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Services","depth":13,"bounds":{"left":0.1390625,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"Search","depth":16,"bounds":{"left":0.15859374,"top":0.054166667,"width":0.2109375,"height":0.020833334},"role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Ask Amazon Q","depth":15,"bounds":{"left":0.35390624,"top":0.05625,"width":0.01171875,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[Option+S]","depth":16,"bounds":{"left":0.32851562,"top":0.058333334,"width":0.02734375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"CloudShell","depth":14,"bounds":{"left":0.78046876,"top":0.047916666,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Notifications (none available)","depth":16,"bounds":{"left":0.7992188,"top":0.050694443,"width":0.01953125,"height":0.027777778},"help_text":"Notifications","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Help & support","depth":15,"bounds":{"left":0.81875,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Settings","depth":15,"bounds":{"left":0.8382813,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"United States (Ohio)","depth":15,"bounds":{"left":0.8578125,"top":0.047916666,"width":0.06328125,"height":0.033333335},"value":"United States (Ohio)","help_text":"United States (Ohio)","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"United States (Ohio)","depth":17,"bounds":{"left":0.86445314,"top":0.059722222,"width":0.04375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"PROD","depth":15,"bounds":{"left":0.92109376,"top":0.047916666,"width":0.07890624,"height":0.033333335},"help_text":"Production_View_Only @ jiminny","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Account ID: 4103-4619-5943","depth":19,"bounds":{"left":0.92460936,"top":0.05,"width":0.06367187,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PROD","depth":18,"bounds":{"left":0.97929686,"top":0.065972224,"width":0.0125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"EC2 EC2","depth":16,"bounds":{"left":0.096875,"top":0.083333336,"width":0.023828125,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EC2","depth":18,"bounds":{"left":0.109375,"top":0.088194445,"width":0.008203125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Elastic Container Service Elastic Container Service","depth":16,"bounds":{"left":0.12070312,"top":0.083333336,"width":0.06757812,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Elastic Container Service","depth":18,"bounds":{"left":0.13320312,"top":0.088194445,"width":0.051953126,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"S3 S3","depth":16,"bounds":{"left":0.18828125,"top":0.083333336,"width":0.02109375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"S3","depth":18,"bounds":{"left":0.20078126,"top":0.088194445,"width":0.00546875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CodeDeploy CodeDeploy","depth":16,"bounds":{"left":0.209375,"top":0.083333336,"width":0.04140625,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CodeDeploy","depth":18,"bounds":{"left":0.221875,"top":0.088194445,"width":0.02578125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudWatch CloudWatch","depth":16,"bounds":{"left":0.25078124,"top":0.083333336,"width":0.04140625,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":18,"bounds":{"left":0.26328126,"top":0.088194445,"width":0.02578125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"ElastiCache ElastiCache","depth":16,"bounds":{"left":0.2921875,"top":0.083333336,"width":0.03984375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ElastiCache","depth":18,"bounds":{"left":0.3046875,"top":0.088194445,"width":0.02421875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Aurora and RDS Aurora and RDS","depth":16,"bounds":{"left":0.33203125,"top":0.083333336,"width":0.048828125,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Aurora and RDS","depth":18,"bounds":{"left":0.34453124,"top":0.088194445,"width":0.033203125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon OpenSearch Service Amazon OpenSearch Service","depth":16,"bounds":{"left":0.38085938,"top":0.083333336,"width":0.07421875,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Amazon OpenSearch Service","depth":18,"bounds":{"left":0.39335936,"top":0.088194445,"width":0.0609375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudFront CloudFront","depth":16,"bounds":{"left":0.45507812,"top":0.083333336,"width":0.039453126,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudFront","depth":18,"bounds":{"left":0.4675781,"top":0.088194445,"width":0.023828125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"MediaLive MediaLive","depth":16,"bounds":{"left":0.49453124,"top":0.083333336,"width":0.037109375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"MediaLive","depth":18,"bounds":{"left":0.50703126,"top":0.088194445,"width":0.021484375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open side navigation","depth":13,"bounds":{"left":0.1,"top":0.108333334,"width":0.01171875,"height":0.020833334},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"CloudWatch","depth":14,"bounds":{"left":0.11640625,"top":0.11111111,"width":0.031640626,"height":0.015277778},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":16,"bounds":{"left":0.1171875,"top":0.1125,"width":0.030078124,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Logs Insights","depth":14,"bounds":{"left":0.16054687,"top":0.11180556,"width":0.03359375,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logs Insights","depth":16,"bounds":{"left":0.16054687,"top":0.1125,"width":0.03359375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Query definition","depth":26,"bounds":{"left":0.1140625,"top":0.14652778,"width":0.059375,"height":0.017361112},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Query definition","depth":28,"bounds":{"left":0.10390625,"top":0.14652778,"width":0.06953125,"height":0.017361112},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Info : Query definition","depth":27,"bounds":{"left":0.1765625,"top":0.15208334,"width":0.008984375,"height":0.010416667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"5m (5 Minutes)","depth":27,"bounds":{"left":0.50625,"top":0.14791666,"width":0.014453125,"height":0.013888889},"help_text":"5 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"30m (30 Minutes)","depth":27,"bounds":{"left":0.5296875,"top":0.14791666,"width":0.017578125,"height":0.013888889},"help_text":"30 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"1h (1 Hour)","depth":27,"bounds":{"left":0.5558594,"top":0.14791666,"width":0.012890625,"height":0.013888889},"help_text":"1 Hour","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"3h (3 Hours)","depth":27,"bounds":{"left":0.57773435,"top":0.14791666,"width":0.012890625,"height":0.013888889},"help_text":"3 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"12h (12 Hours)","depth":27,"bounds":{"left":0.5996094,"top":0.14791666,"width":0.015625,"height":0.013888889},"help_text":"12 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Custom","depth":27,"bounds":{"left":0.62421876,"top":0.14791666,"width":0.028515626,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Custom","depth":29,"bounds":{"left":0.62421876,"top":0.14861111,"width":0.019140625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Compare (Off)","depth":26,"bounds":{"left":0.6605469,"top":0.14444445,"width":0.0546875,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":27,"bounds":{"left":0.66914064,"top":0.14930555,"width":0.023046875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.6921875,"top":0.14930555,"width":0.003515625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Off","depth":27,"bounds":{"left":0.69570315,"top":0.14930555,"width":0.008984375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.7046875,"top":0.14930555,"width":0.001953125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Time zone UTC timezone","depth":26,"bounds":{"left":0.71796876,"top":0.14444445,"width":0.054296874,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"UTC timezone","depth":28,"bounds":{"left":0.7230469,"top":0.14930555,"width":0.034765624,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start tailing with selected log group (opens in a new tab)","depth":26,"bounds":{"left":0.7769531,"top":0.14444445,"width":0.056640625,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start tailing","depth":27,"bounds":{"left":0.7933594,"top":0.14930555,"width":0.031640626,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query scope","depth":28,"bounds":{"left":0.10390625,"top":0.18541667,"width":0.03203125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Query scope Log group name","depth":27,"bounds":{"left":0.10390625,"top":0.20555556,"width":0.078125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Log group name","depth":29,"bounds":{"left":0.10898437,"top":0.21041666,"width":0.040625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Select up to 50 log groups","depth":28,"bounds":{"left":0.1890625,"top":0.20555556,"width":0.5175781,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show more chosen log groups","depth":27,"bounds":{"left":0.18867187,"top":0.27222222,"width":0.0984375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Show more chosen log groups (+25)","depth":29,"bounds":{"left":0.19726562,"top":0.27430555,"width":0.0890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Browse","depth":28,"bounds":{"left":0.71132815,"top":0.20902778,"width":0.01796875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":28,"bounds":{"left":0.72929686,"top":0.20902778,"width":0.0015625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Log Groups","depth":27,"bounds":{"left":0.73398435,"top":0.20902778,"width":0.029296875,"height":0.0125},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"bounds":{"left":0.76640624,"top":0.20902778,"width":0.0015625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Facets","depth":27,"bounds":{"left":0.7710937,"top":0.20902778,"width":0.016015625,"height":0.0125},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"bounds":{"left":0.7902344,"top":0.20902778,"width":0.0015625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Lookup tables","depth":27,"bounds":{"left":0.7949219,"top":0.20902778,"width":0.03671875,"height":0.0125},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Undo","depth":28,"bounds":{"left":0.7792969,"top":0.40694445,"width":0.0109375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Redo","depth":28,"bounds":{"left":0.7933594,"top":0.40694445,"width":0.0109375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Logs Insights QL","depth":29,"bounds":{"left":0.11054687,"top":0.43611112,"width":0.06796875,"height":0.022222223},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Query generator","depth":26,"bounds":{"left":0.18164062,"top":0.43333334,"width":0.061328124,"height":0.028472222},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Query generator","depth":28,"bounds":{"left":0.19570312,"top":0.44027779,"width":0.042578124,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fields","depth":28,"bounds":{"left":0.25546876,"top":0.44027779,"width":0.015234375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saved and sample queries","depth":28,"bounds":{"left":0.2878906,"top":0.44027779,"width":0.06640625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query commands","depth":28,"bounds":{"left":0.37148437,"top":0.44027779,"width":0.0453125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Run query","depth":27,"bounds":{"left":0.10390625,"top":0.47083333,"width":0.044140626,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Cancel","depth":27,"bounds":{"left":0.15117188,"top":0.47083333,"width":0.034375,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Save","depth":27,"bounds":{"left":0.18867187,"top":0.47083333,"width":0.02890625,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"History","depth":27,"bounds":{"left":0.29296875,"top":0.47083333,"width":0.036328126,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Logs (-)","depth":25,"bounds":{"left":0.09921875,"top":0.51666665,"width":0.03203125,"height":0.030555556},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Logs","depth":27,"bounds":{"left":0.10390625,"top":0.525,"width":0.013671875,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.119140625,"top":0.525,"width":0.00234375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":27,"bounds":{"left":0.12148438,"top":0.525,"width":0.00234375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.12382813,"top":0.525,"width":0.00234375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Patterns (-)","depth":25,"bounds":{"left":0.13789062,"top":0.51666665,"width":0.04296875,"height":0.030555556},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Patterns","depth":27,"bounds":{"left":0.14257812,"top":0.525,"width":0.024609376,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.1671875,"top":0.525,"width":0.00390625,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":27,"bounds":{"left":0.17109375,"top":0.525,"width":0.002734375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.17382812,"top":0.525,"width":0.001953125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Visualization","depth":25,"bounds":{"left":0.1875,"top":0.51666665,"width":0.048046876,"height":0.030555556},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Visualization","depth":27,"bounds":{"left":0.1921875,"top":0.525,"width":0.03828125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Logs (-)","depth":26,"bounds":{"left":0.103515625,"top":0.5555556,"width":0.026953125,"height":0.017361112},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Logs (-)","depth":27,"bounds":{"left":0.103515625,"top":0.5555556,"width":0.026953125,"height":0.017361112},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize results","depth":26,"bounds":{"left":0.4441406,"top":0.5520833,"width":0.07304688,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize results","depth":27,"bounds":{"left":0.46054688,"top":0.55694443,"width":0.048046876,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Investigate","depth":28,"bounds":{"left":0.5203125,"top":0.5520833,"width":0.062109374,"height":0.022222223},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Investigate","depth":29,"bounds":{"left":0.5375,"top":0.55694443,"width":0.028515626,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Share results","depth":25,"bounds":{"left":0.58554685,"top":0.5520833,"width":0.058984376,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Share results","depth":26,"bounds":{"left":0.60195315,"top":0.55694443,"width":0.033984374,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Export results","depth":28,"bounds":{"left":0.64765626,"top":0.5520833,"width":0.0609375,"height":0.022222223},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Export results","depth":29,"bounds":{"left":0.65625,"top":0.55694443,"width":0.0359375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add to dashboard","depth":26,"bounds":{"left":0.71171874,"top":0.5520833,"width":0.06367187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"No results","depth":27,"bounds":{"left":0.45625,"top":0.59305555,"width":0.025,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Run a query to see related events","depth":27,"bounds":{"left":0.42734376,"top":0.60694444,"width":0.0828125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close saved and sample queries drawer","depth":24,"bounds":{"left":0.97734374,"top":0.14305556,"width":0.0109375,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Queries","depth":23,"bounds":{"left":0.8550781,"top":0.14722222,"width":0.11757813,"height":0.015277778},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Queries","depth":24,"bounds":{"left":0.8550781,"top":0.14722222,"width":0.025,"height":0.015972223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Saved queries","depth":24,"bounds":{"left":0.8550781,"top":0.18055555,"width":0.04453125,"height":0.015972223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saved queries","depth":25,"bounds":{"left":0.8550781,"top":0.18055555,"width":0.04453125,"height":0.015972223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about saved queries (opens in a new tab)","depth":23,"bounds":{"left":0.94921875,"top":0.18263888,"width":0.0359375,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":24,"bounds":{"left":0.94921875,"top":0.18333334,"width":0.028125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Filter by query name","depth":23,"bounds":{"left":0.8550781,"top":0.20208333,"width":0.13007812,"height":0.022222223},"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create query","depth":24,"bounds":{"left":0.8949219,"top":0.23819445,"width":0.050390624,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"CleanDB (14)","depth":26,"bounds":{"left":0.85546875,"top":0.2777778,"width":0.0453125,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"CleanDB (14)","depth":28,"bounds":{"left":0.8628906,"top":0.2777778,"width":0.037890624,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CRM (14)","depth":26,"bounds":{"left":0.85546875,"top":0.3013889,"width":0.03359375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"CRM (14)","depth":28,"bounds":{"left":0.8628906,"top":0.3013889,"width":0.026171874,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dialers (11)","depth":26,"bounds":{"left":0.85546875,"top":0.325,"width":0.040625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Dialers (11)","depth":28,"bounds":{"left":0.8628906,"top":0.325,"width":0.033203125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Integrations (2)","depth":26,"bounds":{"left":0.85546875,"top":0.34861112,"width":0.05234375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Integrations (2)","depth":28,"bounds":{"left":0.8628906,"top":0.34861112,"width":0.044921875,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"LiveCoach (5)","depth":26,"bounds":{"left":0.85546875,"top":0.37222221,"width":0.046484374,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"LiveCoach (5)","depth":28,"bounds":{"left":0.8628906,"top":0.37222221,"width":0.0390625,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Meetings (4)","depth":26,"bounds":{"left":0.85546875,"top":0.39583334,"width":0.043359376,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Meetings (4)","depth":28,"bounds":{"left":0.8628906,"top":0.39583334,"width":0.0359375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notetaker (4)","depth":26,"bounds":{"left":0.85546875,"top":0.41944444,"width":0.04609375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Notetaker (4)","depth":28,"bounds":{"left":0.8628906,"top":0.41944444,"width":0.038671874,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Nudge (2)","depth":26,"bounds":{"left":0.85546875,"top":0.44305557,"width":0.0359375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nudge (2)","depth":28,"bounds":{"left":0.8628906,"top":0.44305557,"width":0.028515626,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Ogi (5)","depth":26,"bounds":{"left":0.85546875,"top":0.46666667,"width":0.02734375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Ogi (5)","depth":28,"bounds":{"left":0.8628906,"top":0.46666667,"width":0.019921875,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Processing team (6)","depth":26,"bounds":{"left":0.85546875,"top":0.49027777,"width":0.064453125,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Processing team (6)","depth":28,"bounds":{"left":0.8628906,"top":0.49027777,"width":0.05703125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Prophet (3)","depth":26,"bounds":{"left":0.85546875,"top":0.5138889,"width":0.040234376,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Prophet (3)","depth":28,"bounds":{"left":0.8628906,"top":0.5138889,"width":0.0328125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"RDS (4)","depth":26,"bounds":{"left":0.85546875,"top":0.5375,"width":0.02890625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"RDS (4)","depth":28,"bounds":{"left":0.8628906,"top":0.5375,"width":0.021484375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recall (6)","depth":26,"bounds":{"left":0.85546875,"top":0.5611111,"width":0.034375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Recall (6)","depth":28,"bounds":{"left":0.8628906,"top":0.5611111,"width":0.026953125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reports (4)","depth":26,"bounds":{"left":0.85546875,"top":0.5847222,"width":0.039453126,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reports (4)","depth":28,"bounds":{"left":0.8628906,"top":0.5847222,"width":0.03203125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Tomov (4)","depth":26,"bounds":{"left":0.85546875,"top":0.60833335,"width":0.03671875,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Tomov (4)","depth":28,"bounds":{"left":0.8628906,"top":0.60833335,"width":0.029296875,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"_General","depth":25,"bounds":{"left":0.8550781,"top":0.63125,"width":0.021875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.8769531,"top":0.63125,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.88203126,"top":0.63125,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.89453125,"top":0.63055557,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"_Planhat Errors","depth":25,"bounds":{"left":0.8550781,"top":0.65208334,"width":0.037890624,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.8929688,"top":0.65208334,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.89804685,"top":0.65208334,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9105469,"top":0.6513889,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Berdock","depth":25,"bounds":{"left":0.8550781,"top":0.67291665,"width":0.019921875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.875,"top":0.67291665,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.88007814,"top":0.67291665,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.8925781,"top":0.6722222,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Command Memory Usage","depth":25,"bounds":{"left":0.8550781,"top":0.69375,"width":0.0640625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.91914064,"top":0.69375,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9242188,"top":0.69375,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.93671876,"top":0.69305557,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Conference Failure","depth":25,"bounds":{"left":0.8550781,"top":0.71458334,"width":0.04609375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.90117186,"top":0.71458334,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.90625,"top":0.71458334,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.91875,"top":0.7138889,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer API response time","depth":25,"bounds":{"left":0.8550781,"top":0.73541665,"width":0.06992187,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.925,"top":0.73541665,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.93007815,"top":0.73541665,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.94257814,"top":0.7347222,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DB Errors","depth":25,"bounds":{"left":0.8550781,"top":0.75625,"width":0.023046875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.878125,"top":0.75625,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.88320315,"top":0.75625,"width":0.012890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.8960937,"top":0.75555557,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Duplicated track event","depth":25,"bounds":{"left":0.8550781,"top":0.77708334,"width":0.055859376,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.9109375,"top":0.77708334,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9160156,"top":0.77708334,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9285156,"top":0.7763889,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Emo(Activity Log)","depth":25,"bounds":{"left":0.8550781,"top":0.79791665,"width":0.04375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.89882815,"top":0.79791665,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9039062,"top":0.79791665,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9164063,"top":0.7972222,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Encoding steps logs","depth":25,"bounds":{"left":0.8550781,"top":0.81875,"width":0.048828125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.9039062,"top":0.81875,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.90898436,"top":0.81875,"width":0.012890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.921875,"top":0.81805557,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fatal Errors","depth":25,"bounds":{"left":0.8550781,"top":0.83958334,"width":0.028125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.88320315,"top":0.83958334,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.8882812,"top":0.83958334,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9007813,"top":0.8388889,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Find in message","depth":25,"bounds":{"left":0.8550781,"top":0.86041665,"width":0.039453126,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.89453125,"top":0.86041665,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.8996094,"top":0.86041665,"width":0.012890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9125,"top":0.8597222,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"find no match with user locales","depth":25,"bounds":{"left":0.8550781,"top":0.88125,"width":0.07734375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.93242186,"top":0.88125,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9375,"top":0.88125,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.95,"top":0.88055557,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For Activity UUID","depth":25,"bounds":{"left":0.8550781,"top":0.90208334,"width":0.042578124,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.89765626,"top":0.90208334,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9027344,"top":0.90208334,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9152344,"top":0.9013889,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Job timeout","depth":25,"bounds":{"left":0.8550781,"top":0.92291665,"width":0.030078124,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.8851563,"top":0.92291665,"width":0.0046875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.88984376,"top":0.92291665,"width":0.012890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9027344,"top":0.9222222,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Kiosk","depth":25,"bounds":{"left":0.8550781,"top":0.94375,"width":0.01328125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.8683594,"top":0.94375,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.8734375,"top":0.94375,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.8859375,"top":0.94305557,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LiveCoachedActivities","depth":25,"bounds":{"left":0.8550781,"top":0.96458334,"width":0.053515624,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.9085938,"top":0.96458334,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.91367185,"top":0.96458334,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9261719,"top":0.9638889,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Login Page Visits","depth":25,"bounds":{"left":0.8550781,"top":0.98541665,"width":0.041796874,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.896875,"top":0.98541665,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9019531,"top":0.98541665,"width":0.012890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.91484374,"top":0.9847222,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logins without valid user","depth":25,"bounds":{"left":0.8550781,"top":1.0,"width":0.062109374,"height":-0.006250024},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.9171875,"top":1.0,"width":0.005078125,"height":-0.006250024},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.92226565,"top":1.0,"width":0.0125,"height":-0.006250024},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.93476564,"top":1.0,"width":0.009375,"height":-0.0055555105},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logouts","depth":25,"bounds":{"left":0.8550781,"top":1.0,"width":0.019921875,"height":-0.027083278},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.875,"top":1.0,"width":0.005078125,"height":-0.027083278},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.88007814,"top":1.0,"width":0.0125,"height":-0.027083278},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.8925781,"top":1.0,"width":0.009375,"height":-0.026388884},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Meeting Bot Delays","depth":25,"bounds":{"left":0.8550781,"top":1.0,"width":0.048046876,"height":-0.04791665},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.903125,"top":1.0,"width":0.0046875,"height":-0.04791665},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9078125,"top":1.0,"width":0.012890625,"height":-0.04791665},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9207031,"top":1.0,"width":0.009375,"height":-0.047222257},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"MeetingOwner","depth":25,"bounds":{"left":0.8550781,"top":1.0,"width":0.03671875,"height":-0.068750024},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.8917969,"top":1.0,"width":0.005078125,"height":-0.068750024},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.896875,"top":1.0,"width":0.0125,"height":-0.068750024},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.909375,"top":1.0,"width":0.009375,"height":-0.06805551},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Parse Nginx Access Log","depth":25,"bounds":{"left":0.8550781,"top":1.0,"width":0.05703125,"height":-0.08958328},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.9121094,"top":1.0,"width":0.005078125,"height":-0.08958328},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9171875,"top":1.0,"width":0.012890625,"height":-0.08958328},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.93007815,"top":1.0,"width":0.009375,"height":-0.08888888},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Recall error - rate limits or not enough bots","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search by activity","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Slow Http Requests","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Slow PHP log","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Slow RDS queries","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"test","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Sample queries","depth":24,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sample queries","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about sample queries (opens in a new tab)","depth":23,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Common queries","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Common queries","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Lambda","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lambda","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"VPC Flow Logs","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"VPC Flow Logs","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudTrail","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"CloudTrail","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"NetworkFirewall","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"NetworkFirewall","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Route53","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Route53","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"AWS AppSync","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"AWS AppSync","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"NAT Gateway","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"NAT Gateway","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"IoT","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"IoT","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Elemental MediaPackage V2 Access Logs","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Elemental MediaPackage V2 Access Logs","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"SES Mail Manager","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"SES Mail Manager","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon Q Business Conversation Log","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Amazon Q Business Conversation Log","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudShell","depth":12,"bounds":{"left":0.1,"top":0.98125,"width":0.03125,"height":0.013888889},"help_text":"Open CloudShell","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudShell","depth":14,"bounds":{"left":0.10820313,"top":0.98333335,"width":0.023046875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Feedback","depth":11,"bounds":{"left":0.14101562,"top":0.98333335,"width":0.019921875,"height":0.009722223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feedback","depth":13,"bounds":{"left":0.14101562,"top":0.98333335,"width":0.019921875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"©","depth":12,"bounds":{"left":0.784375,"top":0.98333335,"width":0.0046875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":12,"bounds":{"left":0.7890625,"top":0.98333335,"width":0.0109375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"bounds":{"left":0.8,"top":0.98333335,"width":0.00234375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Amazon Web Services, Inc.","depth":12,"bounds":{"left":0.8023437,"top":0.98333335,"width":0.05625,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or its affiliates.","depth":12,"bounds":{"left":0.85976565,"top":0.98333335,"width":0.031640626,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Privacy","depth":13,"bounds":{"left":0.903125,"top":0.9826389,"width":0.016796876,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Privacy","depth":14,"bounds":{"left":0.9039062,"top":0.98333335,"width":0.015234375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Terms","depth":13,"bounds":{"left":0.9296875,"top":0.9826389,"width":0.014453125,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Terms","depth":14,"bounds":{"left":0.93046874,"top":0.98333335,"width":0.012890625,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Cookie preferences","depth":13,"bounds":{"left":0.95390624,"top":0.98333335,"width":0.040234376,"height":0.009722223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
7657383134684988950
|
9084990669898363447
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom
Custom
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Logs (-)
Logs
(
-
)
Patterns (-)
Patterns
(
-
)
Visualization
Visualization
Logs (-)
Logs (-)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
No results
Run a query to see related events
Close saved and sample queries drawer
Queries
Queries
Saved queries
Saved queries
Learn more about saved queries (opens in a new tab)
Learn more
Filter by query name
Create query
CleanDB (14)
CleanDB (14)
CRM (14)
CRM (14)
Dialers (11)
Dialers (11)
Integrations (2)
Integrations (2)
LiveCoach (5)
LiveCoach (5)
Meetings (4)
Meetings (4)
Notetaker (4)
Notetaker (4)
Nudge (2)
Nudge (2)
Ogi (5)
Ogi (5)
Processing team (6)
Processing team (6)
Prophet (3)
Prophet (3)
RDS (4)
RDS (4)
Recall (6)
Recall (6)
Reports (4)
Reports (4)
Tomov (4)
Tomov (4)
_General
-
CWLI
Use as parameterized query
_Planhat Errors
-
CWLI
Use as parameterized query
Berdock
-
CWLI
Use as parameterized query
Command Memory Usage
-
CWLI
Use as parameterized query
Conference Failure
-
CWLI
Use as parameterized query
Customer API response time
-
CWLI
Use as parameterized query
DB Errors
-
CWLI
Use as parameterized query
Duplicated track event
-
CWLI
Use as parameterized query
Emo(Activity Log)
-
CWLI
Use as parameterized query
Encoding steps logs
-
CWLI
Use as parameterized query
Fatal Errors
-
CWLI
Use as parameterized query
Find in message
-
CWLI
Use as parameterized query
find no match with user locales
-
CWLI
Use as parameterized query
For Activity UUID
-
CWLI
Use as parameterized query
Job timeout
-
CWLI
Use as parameterized query
Kiosk
-
CWLI
Use as parameterized query
LiveCoachedActivities
-
CWLI
Use as parameterized query
Login Page Visits
-
CWLI
Use as parameterized query
Logins without valid user
-
CWLI
Use as parameterized query
Logouts
-
CWLI
Use as parameterized query
Meeting Bot Delays
-
CWLI
Use as parameterized query
MeetingOwner
-
CWLI
Use as parameterized query
Parse Nginx Access Log
-
CWLI
Use as parameterized query
Recall error - rate limits or not enough bots
-
CWLI
Use as parameterized query
Search by activity
-
CWLI
Use as parameterized query
Slow Http Requests
-
CWLI
Use as parameterized query
Slow PHP log
-
CWLI
Use as parameterized query
Slow RDS queries
-
CWLI
Use as parameterized query
test
-
CWLI
Use as parameterized query
Sample queries
Sample queries
Learn more about sample queries (opens in a new tab)
Learn more
Common queries
Common queries
Lambda
Lambda
VPC Flow Logs
VPC Flow Logs
CloudTrail
CloudTrail
NetworkFirewall
NetworkFirewall
Route53
Route53
AWS AppSync
AWS AppSync
NAT Gateway
NAT Gateway
IoT
IoT
Elemental MediaPackage V2 Access Logs
Elemental MediaPackage V2 Access Logs
SES Mail Manager
SES Mail Manager
Amazon Q Business Conversation Log
Amazon Q Business Conversation Log
CloudShell
CloudShell
Feedback
Feedback
©
2026
,
Amazon Web Services, Inc.
or its affiliates.
Privacy
Privacy
Terms
Terms
Cookie preferences...
|
41414
|
|
41417
|
880
|
10
|
2026-04-17T06:13:05.275186+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-17/1776 /Users/lukas/.screenpipe/data/data/2026-04-17/1776406385275_m2.jpg...
|
Firefox
|
CloudWatch | us-east-2 — Work
|
1
|
us-east-2.console.aws.amazon.com/cloudwatch/home?r us-east-2.console.aws.amazon.com/cloudwatch/home?region=us-east-2#logsV2:logs-insights$3FqueryDetail$3D~(end~0~start~-3600~timeType~'RELATIVE~tz~'UTC~unit~'seconds~editorString~'fields*20*40timestamp*2c*20*40message*2c*20*40logStream*2c*20*40log*0a*7c*20filter*20*40message*20like*20*2fXXXXX*2f*20*0a*7c*20filter*20*40message*20not*20like*20*2fAnalytic*2f*20*7c*20filter*20*40message*20not*20like*20*2fTranscript*2f*0a*7c*20filter*20*40message*20not*20like*20*2fWebhook*2f*20*7c*20filter*20*40message*20not*20like*20*2fMeetingBot*2f*20*0a*7c*20limit*2010000~queryId~'0551e814-f51a-4339-8372-80d7ba4cef27~source~(~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-analytics~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-app~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-audio~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-calendar~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-conferences~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-crm-sync~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-default~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-delayed~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-dialers~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-dialers-fifo~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-download~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-emails~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-meeting-bot~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-nudges~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-1~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-2~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-3~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-4~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-5~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-delayed~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-softphone~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-video~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-video-app~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aphp~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aphp-app)~lang~'CWLI~logClass~'STANDARD~queryBy~'logGroupName)...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom
Custom
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Logs (-)
Logs
(
-
)
Patterns (-)
Patterns
(
-
)
Visualization
Visualization
Logs (-)
Logs (-)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
No results
Run a query to see related events
Close saved and sample queries drawer
Queries
Queries
Saved queries
Saved queries
Learn more about saved queries (opens in a new tab)
Learn more
Filter by query name
Create query
CleanDB (14)
CleanDB (14)
CRM (14)
CRM (14)
Dialers (11)
Dialers (11)
Integrations (2)
Integrations (2)
LiveCoach (5)
LiveCoach (5)
Meetings (4)
Meetings (4)
Notetaker (4)
Notetaker (4)
Nudge (2)
Nudge (2)
Ogi (5)
Ogi (5)
Processing team (6)
Processing team (6)
Prophet (3)
Prophet (3)
RDS (4)
RDS (4)
Recall (6)
Recall (6)
Reports (4)
Reports (4)
Tomov (4)
Tomov (4)
_General
-
CWLI
Use as parameterized query
_Planhat Errors
-
CWLI
Use as parameterized query
Berdock
-
CWLI
Use as parameterized query
Command Memory Usage
-
CWLI
Use as parameterized query
Conference Failure
-
CWLI
Use as parameterized query
Customer API response time
-
CWLI
Use as parameterized query
DB Errors
-
CWLI
Use as parameterized query
Duplicated track event
-
CWLI
Use as parameterized query
Emo(Activity Log)
-
CWLI
Use as parameterized query
Encoding steps logs
-
CWLI
Use as parameterized query
Fatal Errors
-
CWLI
Use as parameterized query
Find in message
-
CWLI
Use as parameterized query
find no match with user locales
-
CWLI
Use as parameterized query
For Activity UUID
-
CWLI
Use as parameterized query
Job timeout
-
CWLI
Use as parameterized query
Kiosk
-
CWLI
Use as parameterized query
LiveCoachedActivities
-
CWLI
Use as parameterized query
Login Page Visits
-
CWLI
Use as parameterized query
Logins without valid user
-
CWLI
Use as parameterized query
Logouts
-...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.045138888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.05486111,"width":0.11875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"bounds":{"left":0.0,"top":0.07361111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"bounds":{"left":0.015625,"top":0.083333336,"width":0.11171875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.10208333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.015625,"top":0.11180556,"width":0.017578125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":4,"bounds":{"left":0.0,"top":0.13055556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":5,"bounds":{"left":0.015625,"top":0.14027777,"width":0.53398436,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.15902779,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.16875,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.16527778,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.1875,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.19722222,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | eu-west-1","depth":4,"bounds":{"left":0.0,"top":0.21597221,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | eu-west-1","depth":5,"bounds":{"left":0.015625,"top":0.22569445,"width":0.0875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.24583334,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"AWS Console Home","depth":13,"bounds":{"left":0.09375,"top":0.047916666,"width":0.025390625,"height":0.033333335},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to Main Content","depth":13,"bounds":{"left":0.09335937,"top":0.047222223,"width":0.0015625,"height":0.0013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to Main Content","depth":14,"bounds":{"left":0.09414063,"top":0.047916666,"width":0.01953125,"height":0.045138888},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon Q","depth":14,"bounds":{"left":0.11953125,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Services","depth":13,"bounds":{"left":0.1390625,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"Search","depth":16,"bounds":{"left":0.15859374,"top":0.054166667,"width":0.2109375,"height":0.020833334},"role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Ask Amazon Q","depth":15,"bounds":{"left":0.35390624,"top":0.05625,"width":0.01171875,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[Option+S]","depth":16,"bounds":{"left":0.32851562,"top":0.058333334,"width":0.02734375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"CloudShell","depth":14,"bounds":{"left":0.78046876,"top":0.047916666,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Notifications (none available)","depth":16,"bounds":{"left":0.7992188,"top":0.050694443,"width":0.01953125,"height":0.027777778},"help_text":"Notifications","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Help & support","depth":15,"bounds":{"left":0.81875,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Settings","depth":15,"bounds":{"left":0.8382813,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"United States (Ohio)","depth":15,"bounds":{"left":0.8578125,"top":0.047916666,"width":0.06328125,"height":0.033333335},"value":"United States (Ohio)","help_text":"United States (Ohio)","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"United States (Ohio)","depth":17,"bounds":{"left":0.86445314,"top":0.059722222,"width":0.04375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"PROD","depth":15,"bounds":{"left":0.92109376,"top":0.047916666,"width":0.07890624,"height":0.033333335},"help_text":"Production_View_Only @ jiminny","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Account ID: 4103-4619-5943","depth":19,"bounds":{"left":0.92460936,"top":0.05,"width":0.06367187,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PROD","depth":18,"bounds":{"left":0.97929686,"top":0.065972224,"width":0.0125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"EC2 EC2","depth":16,"bounds":{"left":0.096875,"top":0.083333336,"width":0.023828125,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EC2","depth":18,"bounds":{"left":0.109375,"top":0.088194445,"width":0.008203125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Elastic Container Service Elastic Container Service","depth":16,"bounds":{"left":0.12070312,"top":0.083333336,"width":0.06757812,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Elastic Container Service","depth":18,"bounds":{"left":0.13320312,"top":0.088194445,"width":0.051953126,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"S3 S3","depth":16,"bounds":{"left":0.18828125,"top":0.083333336,"width":0.02109375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"S3","depth":18,"bounds":{"left":0.20078126,"top":0.088194445,"width":0.00546875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CodeDeploy CodeDeploy","depth":16,"bounds":{"left":0.209375,"top":0.083333336,"width":0.04140625,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CodeDeploy","depth":18,"bounds":{"left":0.221875,"top":0.088194445,"width":0.02578125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudWatch CloudWatch","depth":16,"bounds":{"left":0.25078124,"top":0.083333336,"width":0.04140625,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":18,"bounds":{"left":0.26328126,"top":0.088194445,"width":0.02578125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"ElastiCache ElastiCache","depth":16,"bounds":{"left":0.2921875,"top":0.083333336,"width":0.03984375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ElastiCache","depth":18,"bounds":{"left":0.3046875,"top":0.088194445,"width":0.02421875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Aurora and RDS Aurora and RDS","depth":16,"bounds":{"left":0.33203125,"top":0.083333336,"width":0.048828125,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Aurora and RDS","depth":18,"bounds":{"left":0.34453124,"top":0.088194445,"width":0.033203125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon OpenSearch Service Amazon OpenSearch Service","depth":16,"bounds":{"left":0.38085938,"top":0.083333336,"width":0.07421875,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Amazon OpenSearch Service","depth":18,"bounds":{"left":0.39335936,"top":0.088194445,"width":0.0609375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudFront CloudFront","depth":16,"bounds":{"left":0.45507812,"top":0.083333336,"width":0.039453126,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudFront","depth":18,"bounds":{"left":0.4675781,"top":0.088194445,"width":0.023828125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"MediaLive MediaLive","depth":16,"bounds":{"left":0.49453124,"top":0.083333336,"width":0.037109375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"MediaLive","depth":18,"bounds":{"left":0.50703126,"top":0.088194445,"width":0.021484375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open side navigation","depth":13,"bounds":{"left":0.1,"top":0.108333334,"width":0.01171875,"height":0.020833334},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"CloudWatch","depth":14,"bounds":{"left":0.11640625,"top":0.11111111,"width":0.031640626,"height":0.015277778},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":16,"bounds":{"left":0.1171875,"top":0.1125,"width":0.030078124,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Logs Insights","depth":14,"bounds":{"left":0.16054687,"top":0.11180556,"width":0.03359375,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logs Insights","depth":16,"bounds":{"left":0.16054687,"top":0.1125,"width":0.03359375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Query definition","depth":26,"bounds":{"left":0.1140625,"top":0.14652778,"width":0.059375,"height":0.017361112},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Query definition","depth":28,"bounds":{"left":0.10390625,"top":0.14652778,"width":0.06953125,"height":0.017361112},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Info : Query definition","depth":27,"bounds":{"left":0.1765625,"top":0.15208334,"width":0.008984375,"height":0.010416667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"5m (5 Minutes)","depth":27,"bounds":{"left":0.50625,"top":0.14791666,"width":0.014453125,"height":0.013888889},"help_text":"5 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"30m (30 Minutes)","depth":27,"bounds":{"left":0.5296875,"top":0.14791666,"width":0.017578125,"height":0.013888889},"help_text":"30 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"1h (1 Hour)","depth":27,"bounds":{"left":0.5558594,"top":0.14791666,"width":0.012890625,"height":0.013888889},"help_text":"1 Hour","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"3h (3 Hours)","depth":27,"bounds":{"left":0.57773435,"top":0.14791666,"width":0.012890625,"height":0.013888889},"help_text":"3 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"12h (12 Hours)","depth":27,"bounds":{"left":0.5996094,"top":0.14791666,"width":0.015625,"height":0.013888889},"help_text":"12 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Custom","depth":27,"bounds":{"left":0.62421876,"top":0.14791666,"width":0.028515626,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Custom","depth":29,"bounds":{"left":0.62421876,"top":0.14861111,"width":0.019140625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Compare (Off)","depth":26,"bounds":{"left":0.6605469,"top":0.14444445,"width":0.0546875,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":27,"bounds":{"left":0.66914064,"top":0.14930555,"width":0.023046875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.6921875,"top":0.14930555,"width":0.003515625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Off","depth":27,"bounds":{"left":0.69570315,"top":0.14930555,"width":0.008984375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.7046875,"top":0.14930555,"width":0.001953125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Time zone UTC timezone","depth":26,"bounds":{"left":0.71796876,"top":0.14444445,"width":0.054296874,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"UTC timezone","depth":28,"bounds":{"left":0.7230469,"top":0.14930555,"width":0.034765624,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start tailing with selected log group (opens in a new tab)","depth":26,"bounds":{"left":0.7769531,"top":0.14444445,"width":0.056640625,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start tailing","depth":27,"bounds":{"left":0.7933594,"top":0.14930555,"width":0.031640626,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query scope","depth":28,"bounds":{"left":0.10390625,"top":0.18541667,"width":0.03203125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Query scope Log group name","depth":27,"bounds":{"left":0.10390625,"top":0.20555556,"width":0.078125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Log group name","depth":29,"bounds":{"left":0.10898437,"top":0.21041666,"width":0.040625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Select up to 50 log groups","depth":28,"bounds":{"left":0.1890625,"top":0.20555556,"width":0.5175781,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show more chosen log groups","depth":27,"bounds":{"left":0.18867187,"top":0.27222222,"width":0.0984375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Show more chosen log groups (+25)","depth":29,"bounds":{"left":0.19726562,"top":0.27430555,"width":0.0890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Browse","depth":28,"bounds":{"left":0.71132815,"top":0.20902778,"width":0.01796875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":28,"bounds":{"left":0.72929686,"top":0.20902778,"width":0.0015625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Log Groups","depth":27,"bounds":{"left":0.73398435,"top":0.20902778,"width":0.029296875,"height":0.0125},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"bounds":{"left":0.76640624,"top":0.20902778,"width":0.0015625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Facets","depth":27,"bounds":{"left":0.7710937,"top":0.20902778,"width":0.016015625,"height":0.0125},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"bounds":{"left":0.7902344,"top":0.20902778,"width":0.0015625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Lookup tables","depth":27,"bounds":{"left":0.7949219,"top":0.20902778,"width":0.03671875,"height":0.0125},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Undo","depth":28,"bounds":{"left":0.7792969,"top":0.40694445,"width":0.0109375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Redo","depth":28,"bounds":{"left":0.7933594,"top":0.40694445,"width":0.0109375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Logs Insights QL","depth":29,"bounds":{"left":0.11054687,"top":0.43611112,"width":0.06796875,"height":0.022222223},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Query generator","depth":26,"bounds":{"left":0.18164062,"top":0.43333334,"width":0.061328124,"height":0.028472222},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Query generator","depth":28,"bounds":{"left":0.19570312,"top":0.44027779,"width":0.042578124,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fields","depth":28,"bounds":{"left":0.25546876,"top":0.44027779,"width":0.015234375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saved and sample queries","depth":28,"bounds":{"left":0.2878906,"top":0.44027779,"width":0.06640625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query commands","depth":28,"bounds":{"left":0.37148437,"top":0.44027779,"width":0.0453125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Run query","depth":27,"bounds":{"left":0.10390625,"top":0.47083333,"width":0.044140626,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Cancel","depth":27,"bounds":{"left":0.15117188,"top":0.47083333,"width":0.034375,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Save","depth":27,"bounds":{"left":0.18867187,"top":0.47083333,"width":0.02890625,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"History","depth":27,"bounds":{"left":0.29296875,"top":0.47083333,"width":0.036328126,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Logs (-)","depth":25,"bounds":{"left":0.09921875,"top":0.51666665,"width":0.03203125,"height":0.030555556},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Logs","depth":27,"bounds":{"left":0.10390625,"top":0.525,"width":0.013671875,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.119140625,"top":0.525,"width":0.00234375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":27,"bounds":{"left":0.12148438,"top":0.525,"width":0.00234375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.12382813,"top":0.525,"width":0.00234375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Patterns (-)","depth":25,"bounds":{"left":0.13789062,"top":0.51666665,"width":0.04296875,"height":0.030555556},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Patterns","depth":27,"bounds":{"left":0.14257812,"top":0.525,"width":0.024609376,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.1671875,"top":0.525,"width":0.00390625,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":27,"bounds":{"left":0.17109375,"top":0.525,"width":0.002734375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.17382812,"top":0.525,"width":0.001953125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Visualization","depth":25,"bounds":{"left":0.1875,"top":0.51666665,"width":0.048046876,"height":0.030555556},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Visualization","depth":27,"bounds":{"left":0.1921875,"top":0.525,"width":0.03828125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Logs (-)","depth":26,"bounds":{"left":0.103515625,"top":0.5555556,"width":0.026953125,"height":0.017361112},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Logs (-)","depth":27,"bounds":{"left":0.103515625,"top":0.5555556,"width":0.026953125,"height":0.017361112},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize results","depth":26,"bounds":{"left":0.4441406,"top":0.5520833,"width":0.07304688,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize results","depth":27,"bounds":{"left":0.46054688,"top":0.55694443,"width":0.048046876,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Investigate","depth":28,"bounds":{"left":0.5203125,"top":0.5520833,"width":0.062109374,"height":0.022222223},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Investigate","depth":29,"bounds":{"left":0.5375,"top":0.55694443,"width":0.028515626,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Share results","depth":25,"bounds":{"left":0.58554685,"top":0.5520833,"width":0.058984376,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Share results","depth":26,"bounds":{"left":0.60195315,"top":0.55694443,"width":0.033984374,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Export results","depth":28,"bounds":{"left":0.64765626,"top":0.5520833,"width":0.0609375,"height":0.022222223},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Export results","depth":29,"bounds":{"left":0.65625,"top":0.55694443,"width":0.0359375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add to dashboard","depth":26,"bounds":{"left":0.71171874,"top":0.5520833,"width":0.06367187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"No results","depth":27,"bounds":{"left":0.45625,"top":0.59305555,"width":0.025,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Run a query to see related events","depth":27,"bounds":{"left":0.42734376,"top":0.60694444,"width":0.0828125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close saved and sample queries drawer","depth":24,"bounds":{"left":0.97734374,"top":0.14305556,"width":0.0109375,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Queries","depth":23,"bounds":{"left":0.8550781,"top":0.14722222,"width":0.11757813,"height":0.015277778},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Queries","depth":24,"bounds":{"left":0.8550781,"top":0.14722222,"width":0.025,"height":0.015972223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Saved queries","depth":24,"bounds":{"left":0.8550781,"top":0.18055555,"width":0.04453125,"height":0.015972223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saved queries","depth":25,"bounds":{"left":0.8550781,"top":0.18055555,"width":0.04453125,"height":0.015972223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about saved queries (opens in a new tab)","depth":23,"bounds":{"left":0.94921875,"top":0.18263888,"width":0.0359375,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":24,"bounds":{"left":0.94921875,"top":0.18333334,"width":0.028125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Filter by query name","depth":23,"bounds":{"left":0.8550781,"top":0.20208333,"width":0.13007812,"height":0.022222223},"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create query","depth":24,"bounds":{"left":0.8949219,"top":0.23819445,"width":0.050390624,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"CleanDB (14)","depth":26,"bounds":{"left":0.85546875,"top":0.2777778,"width":0.0453125,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"CleanDB (14)","depth":28,"bounds":{"left":0.8628906,"top":0.2777778,"width":0.037890624,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CRM (14)","depth":26,"bounds":{"left":0.85546875,"top":0.3013889,"width":0.03359375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"CRM (14)","depth":28,"bounds":{"left":0.8628906,"top":0.3013889,"width":0.026171874,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dialers (11)","depth":26,"bounds":{"left":0.85546875,"top":0.325,"width":0.040625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Dialers (11)","depth":28,"bounds":{"left":0.8628906,"top":0.325,"width":0.033203125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Integrations (2)","depth":26,"bounds":{"left":0.85546875,"top":0.34861112,"width":0.05234375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Integrations (2)","depth":28,"bounds":{"left":0.8628906,"top":0.34861112,"width":0.044921875,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"LiveCoach (5)","depth":26,"bounds":{"left":0.85546875,"top":0.37222221,"width":0.046484374,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"LiveCoach (5)","depth":28,"bounds":{"left":0.8628906,"top":0.37222221,"width":0.0390625,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Meetings (4)","depth":26,"bounds":{"left":0.85546875,"top":0.39583334,"width":0.043359376,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Meetings (4)","depth":28,"bounds":{"left":0.8628906,"top":0.39583334,"width":0.0359375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notetaker (4)","depth":26,"bounds":{"left":0.85546875,"top":0.41944444,"width":0.04609375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Notetaker (4)","depth":28,"bounds":{"left":0.8628906,"top":0.41944444,"width":0.038671874,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Nudge (2)","depth":26,"bounds":{"left":0.85546875,"top":0.44305557,"width":0.0359375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nudge (2)","depth":28,"bounds":{"left":0.8628906,"top":0.44305557,"width":0.028515626,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Ogi (5)","depth":26,"bounds":{"left":0.85546875,"top":0.46666667,"width":0.02734375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Ogi (5)","depth":28,"bounds":{"left":0.8628906,"top":0.46666667,"width":0.019921875,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Processing team (6)","depth":26,"bounds":{"left":0.85546875,"top":0.49027777,"width":0.064453125,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Processing team (6)","depth":28,"bounds":{"left":0.8628906,"top":0.49027777,"width":0.05703125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Prophet (3)","depth":26,"bounds":{"left":0.85546875,"top":0.5138889,"width":0.040234376,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Prophet (3)","depth":28,"bounds":{"left":0.8628906,"top":0.5138889,"width":0.0328125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"RDS (4)","depth":26,"bounds":{"left":0.85546875,"top":0.5375,"width":0.02890625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"RDS (4)","depth":28,"bounds":{"left":0.8628906,"top":0.5375,"width":0.021484375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recall (6)","depth":26,"bounds":{"left":0.85546875,"top":0.5611111,"width":0.034375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Recall (6)","depth":28,"bounds":{"left":0.8628906,"top":0.5611111,"width":0.026953125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reports (4)","depth":26,"bounds":{"left":0.85546875,"top":0.5847222,"width":0.039453126,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reports (4)","depth":28,"bounds":{"left":0.8628906,"top":0.5847222,"width":0.03203125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Tomov (4)","depth":26,"bounds":{"left":0.85546875,"top":0.60833335,"width":0.03671875,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Tomov (4)","depth":28,"bounds":{"left":0.8628906,"top":0.60833335,"width":0.029296875,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"_General","depth":25,"bounds":{"left":0.8550781,"top":0.63125,"width":0.021875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.8769531,"top":0.63125,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.88203126,"top":0.63125,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.89453125,"top":0.63055557,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"_Planhat Errors","depth":25,"bounds":{"left":0.8550781,"top":0.65208334,"width":0.037890624,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.8929688,"top":0.65208334,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.89804685,"top":0.65208334,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9105469,"top":0.6513889,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Berdock","depth":25,"bounds":{"left":0.8550781,"top":0.67291665,"width":0.019921875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.875,"top":0.67291665,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.88007814,"top":0.67291665,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.8925781,"top":0.6722222,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Command Memory Usage","depth":25,"bounds":{"left":0.8550781,"top":0.69375,"width":0.0640625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.91914064,"top":0.69375,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9242188,"top":0.69375,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.93671876,"top":0.69305557,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Conference Failure","depth":25,"bounds":{"left":0.8550781,"top":0.71458334,"width":0.04609375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.90117186,"top":0.71458334,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.90625,"top":0.71458334,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.91875,"top":0.7138889,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer API response time","depth":25,"bounds":{"left":0.8550781,"top":0.73541665,"width":0.06992187,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.925,"top":0.73541665,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.93007815,"top":0.73541665,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.94257814,"top":0.7347222,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DB Errors","depth":25,"bounds":{"left":0.8550781,"top":0.75625,"width":0.023046875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.878125,"top":0.75625,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.88320315,"top":0.75625,"width":0.012890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.8960937,"top":0.75555557,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Duplicated track event","depth":25,"bounds":{"left":0.8550781,"top":0.77708334,"width":0.055859376,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.9109375,"top":0.77708334,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9160156,"top":0.77708334,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9285156,"top":0.7763889,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Emo(Activity Log)","depth":25,"bounds":{"left":0.8550781,"top":0.79791665,"width":0.04375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.89882815,"top":0.79791665,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9039062,"top":0.79791665,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9164063,"top":0.7972222,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Encoding steps logs","depth":25,"bounds":{"left":0.8550781,"top":0.81875,"width":0.048828125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.9039062,"top":0.81875,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.90898436,"top":0.81875,"width":0.012890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.921875,"top":0.81805557,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fatal Errors","depth":25,"bounds":{"left":0.8550781,"top":0.83958334,"width":0.028125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.88320315,"top":0.83958334,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.8882812,"top":0.83958334,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9007813,"top":0.8388889,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Find in message","depth":25,"bounds":{"left":0.8550781,"top":0.86041665,"width":0.039453126,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.89453125,"top":0.86041665,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.8996094,"top":0.86041665,"width":0.012890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9125,"top":0.8597222,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"find no match with user locales","depth":25,"bounds":{"left":0.8550781,"top":0.88125,"width":0.07734375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.93242186,"top":0.88125,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9375,"top":0.88125,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.95,"top":0.88055557,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For Activity UUID","depth":25,"bounds":{"left":0.8550781,"top":0.90208334,"width":0.042578124,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.89765626,"top":0.90208334,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9027344,"top":0.90208334,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9152344,"top":0.9013889,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Job timeout","depth":25,"bounds":{"left":0.8550781,"top":0.92291665,"width":0.030078124,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.8851563,"top":0.92291665,"width":0.0046875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.88984376,"top":0.92291665,"width":0.012890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9027344,"top":0.9222222,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Kiosk","depth":25,"bounds":{"left":0.8550781,"top":0.94375,"width":0.01328125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.8683594,"top":0.94375,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.8734375,"top":0.94375,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.8859375,"top":0.94305557,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LiveCoachedActivities","depth":25,"bounds":{"left":0.8550781,"top":0.96458334,"width":0.053515624,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.9085938,"top":0.96458334,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.91367185,"top":0.96458334,"width":0.0125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.9261719,"top":0.9638889,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Login Page Visits","depth":25,"bounds":{"left":0.8550781,"top":0.98541665,"width":0.041796874,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.896875,"top":0.98541665,"width":0.005078125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.9019531,"top":0.98541665,"width":0.012890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.91484374,"top":0.9847222,"width":0.009375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logins without valid user","depth":25,"bounds":{"left":0.8550781,"top":1.0,"width":0.062109374,"height":-0.006250024},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.9171875,"top":1.0,"width":0.005078125,"height":-0.006250024},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"bounds":{"left":0.92226565,"top":1.0,"width":0.0125,"height":-0.006250024},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"bounds":{"left":0.93476564,"top":1.0,"width":0.009375,"height":-0.0055555105},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logouts","depth":25,"bounds":{"left":0.8550781,"top":1.0,"width":0.019921875,"height":-0.027083278},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"bounds":{"left":0.875,"top":1.0,"width":0.005078125,"height":-0.027083278},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
6061425329263474209
|
9084973079826247863
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom
Custom
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Logs (-)
Logs
(
-
)
Patterns (-)
Patterns
(
-
)
Visualization
Visualization
Logs (-)
Logs (-)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
No results
Run a query to see related events
Close saved and sample queries drawer
Queries
Queries
Saved queries
Saved queries
Learn more about saved queries (opens in a new tab)
Learn more
Filter by query name
Create query
CleanDB (14)
CleanDB (14)
CRM (14)
CRM (14)
Dialers (11)
Dialers (11)
Integrations (2)
Integrations (2)
LiveCoach (5)
LiveCoach (5)
Meetings (4)
Meetings (4)
Notetaker (4)
Notetaker (4)
Nudge (2)
Nudge (2)
Ogi (5)
Ogi (5)
Processing team (6)
Processing team (6)
Prophet (3)
Prophet (3)
RDS (4)
RDS (4)
Recall (6)
Recall (6)
Reports (4)
Reports (4)
Tomov (4)
Tomov (4)
_General
-
CWLI
Use as parameterized query
_Planhat Errors
-
CWLI
Use as parameterized query
Berdock
-
CWLI
Use as parameterized query
Command Memory Usage
-
CWLI
Use as parameterized query
Conference Failure
-
CWLI
Use as parameterized query
Customer API response time
-
CWLI
Use as parameterized query
DB Errors
-
CWLI
Use as parameterized query
Duplicated track event
-
CWLI
Use as parameterized query
Emo(Activity Log)
-
CWLI
Use as parameterized query
Encoding steps logs
-
CWLI
Use as parameterized query
Fatal Errors
-
CWLI
Use as parameterized query
Find in message
-
CWLI
Use as parameterized query
find no match with user locales
-
CWLI
Use as parameterized query
For Activity UUID
-
CWLI
Use as parameterized query
Job timeout
-
CWLI
Use as parameterized query
Kiosk
-
CWLI
Use as parameterized query
LiveCoachedActivities
-
CWLI
Use as parameterized query
Login Page Visits
-
CWLI
Use as parameterized query
Logins without valid user
-
CWLI
Use as parameterized query
Logouts
-...
|
NULL
|
|
41416
|
879
|
9
|
2026-04-17T06:13:05.253163+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-17/1776 /Users/lukas/.screenpipe/data/data/2026-04-17/1776406385253_m1.jpg...
|
Firefox
|
CloudWatch | us-east-2 — Work
|
1
|
us-east-2.console.aws.amazon.com/cloudwatch/home?r us-east-2.console.aws.amazon.com/cloudwatch/home?region=us-east-2#logsV2:logs-insights$3FqueryDetail$3D~(end~0~start~-3600~timeType~'RELATIVE~tz~'UTC~unit~'seconds~editorString~'fields*20*40timestamp*2c*20*40message*2c*20*40logStream*2c*20*40log*0a*7c*20filter*20*40message*20like*20*2fXXXXX*2f*20*0a*7c*20filter*20*40message*20not*20like*20*2fAnalytic*2f*20*7c*20filter*20*40message*20not*20like*20*2fTranscript*2f*0a*7c*20filter*20*40message*20not*20like*20*2fWebhook*2f*20*7c*20filter*20*40message*20not*20like*20*2fMeetingBot*2f*20*0a*7c*20limit*2010000~queryId~'0551e814-f51a-4339-8372-80d7ba4cef27~source~(~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-analytics~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-app~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-audio~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-calendar~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-conferences~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-crm-sync~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-default~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-delayed~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-dialers~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-dialers-fifo~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-download~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-emails~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-meeting-bot~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-nudges~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-1~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-2~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-3~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-4~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-5~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-delayed~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-softphone~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-video~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-video-app~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aphp~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aphp-app)~lang~'CWLI~logClass~'STANDARD~queryBy~'logGroupName)...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom
Custom
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Logs (-)
Logs
(
-
)
Patterns (-)
Patterns
(
-
)
Visualization
Visualization
Logs (-)
Logs (-)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
No results
Run a query to see related events
Close saved and sample queries drawer
Queries
Queries
Saved queries
Saved queries
Learn more about saved queries (opens in a new tab)
Learn more
Filter by query name
Create query
CleanDB (14)
CleanDB (14)
CRM (14)
CRM (14)
Dialers (11)
Dialers (11)
Integrations (2)
Integrations (2)
LiveCoach (5)
LiveCoach (5)
Meetings (4)
Meetings (4)
Notetaker (4)
Notetaker (4)
Nudge (2)
Nudge (2)
Ogi (5)
Ogi (5)
Processing team (6)
Processing team (6)
Prophet (3)
Prophet (3)
RDS (4)
RDS (4)
Recall (6)
Recall (6)
Reports (4)
Reports (4)
Tomov (4)
Tomov (4)
_General
-
CWLI
Use as parameterized query
_Planhat Errors
-
CWLI
Use as parameterized query
Berdock
-
CWLI
Use as parameterized query
Command Memory Usage
-
CWLI
Use as parameterized query
Conference Failure
-
CWLI
Use as parameterized query
Customer API response time
-
CWLI
Use as parameterized query
DB Errors
-
CWLI
Use as parameterized query
Duplicated track event
-
CWLI
Use as parameterized query
Emo(Activity Log)
-
CWLI
Use as parameterized query
Encoding steps logs
-
CWLI
Use as parameterized query
Fatal Errors
-
CWLI...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | eu-west-1","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | eu-west-1","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"AWS Console Home","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to Main Content","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to Main Content","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon Q","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Services","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"Search","depth":16,"role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Ask Amazon Q","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[Option+S]","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"CloudShell","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Notifications (none available)","depth":16,"help_text":"Notifications","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Help & support","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Settings","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"United States (Ohio)","depth":15,"value":"United States (Ohio)","help_text":"United States (Ohio)","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"United States (Ohio)","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"PROD","depth":15,"help_text":"Production_View_Only @ jiminny","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Account ID: 4103-4619-5943","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PROD","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"EC2 EC2","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EC2","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Elastic Container Service Elastic Container Service","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Elastic Container Service","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"S3 S3","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"S3","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CodeDeploy CodeDeploy","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CodeDeploy","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudWatch CloudWatch","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"ElastiCache ElastiCache","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ElastiCache","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Aurora and RDS Aurora and RDS","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Aurora and RDS","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon OpenSearch Service Amazon OpenSearch Service","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Amazon OpenSearch Service","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudFront CloudFront","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudFront","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"MediaLive MediaLive","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"MediaLive","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open side navigation","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"CloudWatch","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Logs Insights","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logs Insights","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Query definition","depth":26,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Query definition","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Info : Query definition","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"5m (5 Minutes)","depth":27,"help_text":"5 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"30m (30 Minutes)","depth":27,"help_text":"30 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"1h (1 Hour)","depth":27,"help_text":"1 Hour","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"3h (3 Hours)","depth":27,"help_text":"3 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"12h (12 Hours)","depth":27,"help_text":"12 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Custom","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Custom","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Compare (Off)","depth":26,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Off","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Time zone UTC timezone","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"UTC timezone","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start tailing with selected log group (opens in a new tab)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start tailing","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query scope","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Query scope Log group name","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Log group name","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Select up to 50 log groups","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show more chosen log groups","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Show more chosen log groups (+25)","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Browse","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Log Groups","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Facets","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Lookup tables","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Undo","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Redo","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Logs Insights QL","depth":29,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Query generator","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Query generator","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fields","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saved and sample queries","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query commands","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Run query","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Cancel","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Save","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"History","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Logs (-)","depth":25,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Logs","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Patterns (-)","depth":25,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Patterns","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Visualization","depth":25,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Visualization","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Logs (-)","depth":26,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Logs (-)","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize results","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize results","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Investigate","depth":28,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Investigate","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Share results","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Share results","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Export results","depth":28,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Export results","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add to dashboard","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"No results","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Run a query to see related events","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close saved and sample queries drawer","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Queries","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Queries","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Saved queries","depth":24,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saved queries","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about saved queries (opens in a new tab)","depth":23,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Filter by query name","depth":23,"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create query","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"CleanDB (14)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"CleanDB (14)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CRM (14)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"CRM (14)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dialers (11)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Dialers (11)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Integrations (2)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Integrations (2)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"LiveCoach (5)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"LiveCoach (5)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Meetings (4)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Meetings (4)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notetaker (4)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Notetaker (4)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Nudge (2)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nudge (2)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Ogi (5)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Ogi (5)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Processing team (6)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Processing team (6)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Prophet (3)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Prophet (3)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"RDS (4)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"RDS (4)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recall (6)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Recall (6)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reports (4)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reports (4)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Tomov (4)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Tomov (4)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"_General","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"_Planhat Errors","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Berdock","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Command Memory Usage","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Conference Failure","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer API response time","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DB Errors","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Duplicated track event","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Emo(Activity Log)","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Encoding steps logs","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fatal Errors","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
2989213197326425537
|
9084902711084167351
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom
Custom
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Logs (-)
Logs
(
-
)
Patterns (-)
Patterns
(
-
)
Visualization
Visualization
Logs (-)
Logs (-)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
No results
Run a query to see related events
Close saved and sample queries drawer
Queries
Queries
Saved queries
Saved queries
Learn more about saved queries (opens in a new tab)
Learn more
Filter by query name
Create query
CleanDB (14)
CleanDB (14)
CRM (14)
CRM (14)
Dialers (11)
Dialers (11)
Integrations (2)
Integrations (2)
LiveCoach (5)
LiveCoach (5)
Meetings (4)
Meetings (4)
Notetaker (4)
Notetaker (4)
Nudge (2)
Nudge (2)
Ogi (5)
Ogi (5)
Processing team (6)
Processing team (6)
Prophet (3)
Prophet (3)
RDS (4)
RDS (4)
Recall (6)
Recall (6)
Reports (4)
Reports (4)
Tomov (4)
Tomov (4)
_General
-
CWLI
Use as parameterized query
_Planhat Errors
-
CWLI
Use as parameterized query
Berdock
-
CWLI
Use as parameterized query
Command Memory Usage
-
CWLI
Use as parameterized query
Conference Failure
-
CWLI
Use as parameterized query
Customer API response time
-
CWLI
Use as parameterized query
DB Errors
-
CWLI
Use as parameterized query
Duplicated track event
-
CWLI
Use as parameterized query
Emo(Activity Log)
-
CWLI
Use as parameterized query
Encoding steps logs
-
CWLI
Use as parameterized query
Fatal Errors
-
CWLI...
|
NULL
|
|
41413
|
879
|
8
|
2026-04-17T06:13:00.067799+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-17/1776 /Users/lukas/.screenpipe/data/data/2026-04-17/1776406380067_m1.jpg...
|
Firefox
|
CloudWatch | us-east-2 — Work
|
1
|
us-east-2.console.aws.amazon.com/cloudwatch/home?r us-east-2.console.aws.amazon.com/cloudwatch/home?region=us-east-2#logsV2:logs-insights$3FqueryDetail$3D~(end~0~start~-3600~timeType~'RELATIVE~tz~'UTC~unit~'seconds~editorString~'fields*20*40timestamp*2c*20*40message*2c*20*40logStream*2c*20*40log*0a*7c*20filter*20*40message*20like*20*2fXXXXX*2f*20*0a*7c*20filter*20*40message*20not*20like*20*2fAnalytic*2f*20*7c*20filter*20*40message*20not*20like*20*2fTranscript*2f*0a*7c*20filter*20*40message*20not*20like*20*2fWebhook*2f*20*7c*20filter*20*40message*20not*20like*20*2fMeetingBot*2f*20*0a*7c*20limit*2010000~queryId~'0551e814-f51a-4339-8372-80d7ba4cef27~source~(~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-analytics~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-app~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-audio~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-calendar~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-conferences~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-crm-sync~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-default~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-delayed~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-dialers~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-dialers-fifo~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-download~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-emails~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-meeting-bot~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-nudges~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-1~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-2~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-3~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-4~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-5~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-delayed~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-softphone~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-video~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-video-app~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aphp~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aphp-app)~lang~'CWLI~logClass~'STANDARD~queryBy~'logGroupName)...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom
Custom
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Logs (-)
Logs
(
-
)
Patterns (-)
Patterns
(
-
)
Visualization
Visualization
Logs (-)
Logs (-)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
No results
Run a query to see related events
Close saved and sample queries drawer
Queries
Queries
Saved queries
Saved queries
Learn more about saved queries (opens in a new tab)
Learn more
Filter by query name
Create query
CleanDB (14)
CleanDB (14)
CRM (14)
CRM (14)
Dialers (11)
Dialers (11)
Integrations (2)
Integrations (2)
LiveCoach (5)
LiveCoach (5)
Meetings (4)
Meetings (4)
Notetaker (4)
Notetaker (4)
Nudge (2)
Nudge (2)
Ogi (5)
Ogi (5)
Processing team (6)
Processing team (6)
Prophet (3)
Prophet (3)
RDS (4)
RDS (4)
Recall (6)
Recall (6)
Reports (4)
Reports (4)
Tomov (4)
Tomov (4)
_General
-
CWLI
Use as parameterized query
_Planhat Errors
-
CWLI
Use as parameterized query
Berdock
-
CWLI
Use as parameterized query
Command Memory Usage
-
CWLI
Use as parameterized query
Conference Failure
-
CWLI
Use as parameterized query
Customer API response time
-
CWLI
Use as parameterized query
DB Errors
-
CWLI
Use as parameterized query
Duplicated track event
-
CWLI
Use as parameterized query
Emo(Activity Log)
-
CWLI
Use as parameterized query
Encoding steps logs
-
CWLI...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | eu-west-1","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | eu-west-1","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"AWS Console Home","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to Main Content","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to Main Content","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon Q","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Services","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"Search","depth":16,"role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Ask Amazon Q","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[Option+S]","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"CloudShell","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Notifications (none available)","depth":16,"help_text":"Notifications","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Help & support","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Settings","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"United States (Ohio)","depth":15,"value":"United States (Ohio)","help_text":"United States (Ohio)","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"United States (Ohio)","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"PROD","depth":15,"help_text":"Production_View_Only @ jiminny","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Account ID: 4103-4619-5943","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PROD","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"EC2 EC2","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EC2","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Elastic Container Service Elastic Container Service","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Elastic Container Service","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"S3 S3","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"S3","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CodeDeploy CodeDeploy","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CodeDeploy","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudWatch CloudWatch","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"ElastiCache ElastiCache","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ElastiCache","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Aurora and RDS Aurora and RDS","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Aurora and RDS","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon OpenSearch Service Amazon OpenSearch Service","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Amazon OpenSearch Service","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudFront CloudFront","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudFront","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"MediaLive MediaLive","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"MediaLive","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open side navigation","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"CloudWatch","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Logs Insights","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logs Insights","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Query definition","depth":26,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Query definition","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Info : Query definition","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"5m (5 Minutes)","depth":27,"help_text":"5 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"30m (30 Minutes)","depth":27,"help_text":"30 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"1h (1 Hour)","depth":27,"help_text":"1 Hour","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"3h (3 Hours)","depth":27,"help_text":"3 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"12h (12 Hours)","depth":27,"help_text":"12 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Custom","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Custom","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Compare (Off)","depth":26,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Off","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Time zone UTC timezone","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"UTC timezone","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start tailing with selected log group (opens in a new tab)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start tailing","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query scope","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Query scope Log group name","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Log group name","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Select up to 50 log groups","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show more chosen log groups","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Show more chosen log groups (+25)","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Browse","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Log Groups","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Facets","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Lookup tables","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Undo","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Redo","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Logs Insights QL","depth":29,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Query generator","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Query generator","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fields","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saved and sample queries","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query commands","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Run query","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Cancel","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Save","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"History","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Logs (-)","depth":25,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Logs","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Patterns (-)","depth":25,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Patterns","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Visualization","depth":25,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Visualization","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Logs (-)","depth":26,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Logs (-)","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize results","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize results","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Investigate","depth":28,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Investigate","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Share results","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Share results","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Export results","depth":28,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Export results","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add to dashboard","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"No results","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Run a query to see related events","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close saved and sample queries drawer","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Queries","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Queries","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Saved queries","depth":24,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saved queries","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about saved queries (opens in a new tab)","depth":23,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Filter by query name","depth":23,"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create query","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"CleanDB (14)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"CleanDB (14)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CRM (14)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"CRM (14)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dialers (11)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Dialers (11)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Integrations (2)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Integrations (2)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"LiveCoach (5)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"LiveCoach (5)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Meetings (4)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Meetings (4)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Notetaker (4)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Notetaker (4)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Nudge (2)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nudge (2)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Ogi (5)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Ogi (5)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Processing team (6)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Processing team (6)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Prophet (3)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Prophet (3)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"RDS (4)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"RDS (4)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Recall (6)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Recall (6)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reports (4)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reports (4)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Tomov (4)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Tomov (4)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"_General","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"_Planhat Errors","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Berdock","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Command Memory Usage","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Conference Failure","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer API response time","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DB Errors","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Duplicated track event","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Emo(Activity Log)","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use as parameterized query","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Encoding steps logs","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CWLI","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
7469075191104089943
|
9084902436210454711
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom
Custom
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Logs (-)
Logs
(
-
)
Patterns (-)
Patterns
(
-
)
Visualization
Visualization
Logs (-)
Logs (-)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
No results
Run a query to see related events
Close saved and sample queries drawer
Queries
Queries
Saved queries
Saved queries
Learn more about saved queries (opens in a new tab)
Learn more
Filter by query name
Create query
CleanDB (14)
CleanDB (14)
CRM (14)
CRM (14)
Dialers (11)
Dialers (11)
Integrations (2)
Integrations (2)
LiveCoach (5)
LiveCoach (5)
Meetings (4)
Meetings (4)
Notetaker (4)
Notetaker (4)
Nudge (2)
Nudge (2)
Ogi (5)
Ogi (5)
Processing team (6)
Processing team (6)
Prophet (3)
Prophet (3)
RDS (4)
RDS (4)
Recall (6)
Recall (6)
Reports (4)
Reports (4)
Tomov (4)
Tomov (4)
_General
-
CWLI
Use as parameterized query
_Planhat Errors
-
CWLI
Use as parameterized query
Berdock
-
CWLI
Use as parameterized query
Command Memory Usage
-
CWLI
Use as parameterized query
Conference Failure
-
CWLI
Use as parameterized query
Customer API response time
-
CWLI
Use as parameterized query
DB Errors
-
CWLI
Use as parameterized query
Duplicated track event
-
CWLI
Use as parameterized query
Emo(Activity Log)
-
CWLI
Use as parameterized query
Encoding steps logs
-
CWLI...
|
41410
|
|
72464
|
1769
|
1
|
2026-04-22T15:50:02.595013+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-22/1776 /Users/lukas/.screenpipe/data/data/2026-04-22/1776873002595_m2.jpg...
|
Finder
|
Copy
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Copying “archive.db” to “screenpipe”
stop progress Copying “archive.db” to “screenpipe”
stop progress
3,30 GB of 5,23 GB - About 2 minutes...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Copying “archive.db” to “screenpipe”","depth":2,"bounds":{"left":0.27460107,"top":0.62889063,"width":0.10405585,"height":0.011173184},"automation_id":"_NS:59","role_description":"text"},{"role":"AXButton","text":"stop progress","depth":2,"bounds":{"left":0.3806516,"top":0.6404629,"width":0.0043218085,"height":0.0103751},"automation_id":"_NS:8","role_description":"button","is_enabled":true,"is_focused":false},{"role":"AXStaticText","text":"3,30 GB of 5,23 GB - About 2 minutes","depth":2,"bounds":{"left":0.27460107,"top":0.6520351,"width":0.10405585,"height":0.011173184},"automation_id":"_NS:89","role_description":"text"}]...
|
4436392955366976095
|
9068333801035922772
|
click
|
hybrid
|
NULL
|
Copying “archive.db” to “screenpipe”
stop progress Copying “archive.db” to “screenpipe”
stop progress
3,30 GB of 5,23 GB - About 2 minutes
ActivityFilesLaterFinderJiminny …..vE) Channels# ai-chapter# alerts# backend# c-learning-people# confusion-clinic# curiosity_lab# deal-insights-dev# engineering# frontend# general# infra-changes#jiminny-bg8 people-with-copilo...8 people-with-zoom-..# platform-team# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...^ Direct messages. Petko KashinskiRP. Stoyan TomovWindowmelpPetko Kashinski• Messagest Add canvasUr Files• има ли всьшYesterday греда за planhatили само продіPetko Kashinski 1:53PMОх, много добър въпрос(3Аз сьм от ония лудите дето тестват само напродLukas Kovalik 1:54 PMаз не сьм чувал за такава но не сьмираbотил no nlanhatKeldntelewi tonteletnPetko Kachincki 1.54 PMoks thyPetko Kachincki 4-48 pMlЛукасИмаш ли минутка за бърз хъдъл :?Lukas Kovallk 6:49 PMздрасти Петко, до сега бях в срещаKaкRо Cтав?Message Petko Kashinski+ Aa €• • 0tscommano.phpscreenpipe• #recvcledo,salite-shmscreenpipe_sync.sh• app_settings.jsondh.salite-waa dbo.salite• screenpipe.dbpipes→Date ModifiedToday at 18:47Today at 18:43Today al 10:2020 Aor 2026 at 20:4918 Apr 2026 at 18:3518 Apr 2026 at 17:4218 Apr 2026 at 1/:1618 Apr 2026 at 17:0516 Apr 2026 at 17:0713 Apr 2026 at 17:2111 Aor 2026 at 16:51iminny.atlassian.net/wiki/spaces/PROD/paçO JIMINNY19.59 GB Folder5,74 GB Folder0,45 0b33 KB15 KBTerminal scripts31 bytes10/ KbrolderZero bytesDocument2,82 GBZero bytes13 KBIDocumentFolderchurned custDealsmeeungsCopying "archive.db* to "screenpipe"3,23 GB of 5,23 GB - About 2 minuteswithout visibkFeedback4 Research & User Feedback+ Create© Jira8: Teams* More|FavouritesE jiminny(* AirDropO Recents# ApplicationsDocumentsii lukasiCloud• iCloud Drive992 Svnc toldeLocationsC DXP4800PLUS-B5F a® Network• CRM• Orange• Red• Yellow• Green• Blue• PurpleO All Tags...100% L2lest> Jazyky> trecycleSyncDatav screenpipe>2026-04-15•2026-04-14› 2026-04-16•2026-04-17•2026-04-20> 2026-04-21db.saliteoipesscreenpipe-day.shscreenpipe.dbtest writeP Ckol> Computer ScienceB ubuntu-24.04.4-live-server-amd64.iso,CODE›Gitarastart machine.wavlocation-historv.isorlocation-history (1) json1910229e6394bdc967d792141382106f.ug-tmpoate Wodmied16 Mar 2026 at 10:3211 Apr 2026 at 15:5320 Apr 2026 at 21:09Today at 18:28Today at 18:2816 Apr 2026 at 9:1315 Aor 2026 at 9:5917 Apr 2026 at 8:5718 Apr 2026 at 13:35Yesterday at 9:10Today at 9:16Today at 18:2814 Apr 2026 at 20:4911 Aor 2026 at 16:51111 Apr 2026 at 17:0013 Apr 2026 at 17:2111 Aor 2026 at 17:2628 Jan 2026 at 19:566 Mar 2026 at 20:0316 Oct 2025 at 14:5628 Jan 2026 at 19:5514 Jun 2008 at 11:0316 Mar 2026 at 6:4016 Mar 2026 at 6:5328 Feb 2026 at 9:08Wed 22 Apr 18:50:03v Kind82,19 GB Folder76,82 GB36.64 GBFolder12,39 GB Folder5,74 GB Folder2,15 GBrolder1.09 GB Folden837,2 MB Folder699,6 MBFolder525,4 MBFolderA50 9 MR Calder1,42 GbDocument13 KBFolder3 KBTerminal scriptsZero bytesDocumentZero bvtesUnix Ex...ble File8,3 GB Folder7,54 CB3.41GBISO Disk Image578 8 MR Folder3,1 MB Folder2 MBWaveform audio1.2MBASON1,2 MB JSONZero bvtes Document1 of 26 selected, 2,03 TB available...
|
NULL
|
|
72873
|
1778
|
9
|
2026-04-23T06:20:33.913737+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-23/1776 /Users/lukas/.screenpipe/data/data/2026-04-23/1776925233913_m1.jpg...
|
PhpStorm
|
faVsco.js – UserTransformer.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams
Tracks
Transcription
Twilio
Users
Vocabulary
Zoom...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20157-AJ-report-not-send-notification, menu","depth":5,"help_text":"Git Branch: JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"13","depth":4,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","depth":4,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"36","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregator.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregatorInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatabaseActivities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatasourceInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivityInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Comments","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Forecast","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Jobs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"QueryBuilder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Services","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ClosingPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CreatedPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Criteria.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaNormalizer.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealContactService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsCriteriaBuilder.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepositoryInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsServiceRepositories.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PerformanceMonitor.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodOptionDecoratorInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodService.php, final class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskTypes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisk.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GroupDealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encoding, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encryption, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ES, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Faker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gecko, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gong, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Locks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Math, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Playlist, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Prophet, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Queue, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Router, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Saml2, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"SCIM, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Seeder, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sentry, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Serializer, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Settings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Slack, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Transcription, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dev","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dialers","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playlists","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Postmark","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Reports","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DeleteReportCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"GenerateMarketingReport.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Team.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Usage.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Teams","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Tracks","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Twilio","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Users","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Vocabulary","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Zoom","depth":10,"role_description":"text"}]...
|
-6035825290081080934
|
9055203785154560316
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams
Tracks
Transcription
Twilio
Users
Vocabulary
Zoom...
|
72871
|
|
72874
|
1779
|
12
|
2026-04-23T06:20:34.001281+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-23/1776 /Users/lukas/.screenpipe/data/data/2026-04-23/1776925234001_m2.jpg...
|
PhpStorm
|
faVsco.js – UserTransformer.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.25731382,"top":0.019952115,"width":0.03856383,"height":0.025538707},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20157-AJ-report-not-send-notification, menu","depth":5,"bounds":{"left":0.29587767,"top":0.019952115,"width":0.10139628,"height":0.025538707},"help_text":"Git Branch: JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.7972075,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"bounds":{"left":0.8125,"top":0.019952115,"width":0.10305851,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"13","depth":4,"bounds":{"left":0.66921544,"top":0.15003991,"width":0.009640957,"height":0.015163607},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.68085104,"top":0.15003991,"width":0.007978723,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.69049203,"top":0.14844373,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.6978058,"top":0.14844373,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","depth":4,"bounds":{"left":0.3700133,"top":0.14684756,"width":0.33477393,"height":0.85315245},"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"36","depth":4,"bounds":{"left":0.96210104,"top":0.10055866,"width":0.010305851,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.9740692,"top":0.09896249,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.98138297,"top":0.09896249,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.24335106,"top":0.047885075,"width":0.024268618,"height":0.024740623},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregator.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregatorInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatabaseActivities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatasourceInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivityInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Comments","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Forecast","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Jobs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"QueryBuilder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Services","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ClosingPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CreatedPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Criteria.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaNormalizer.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealContactService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsCriteriaBuilder.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepositoryInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsServiceRepositories.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PerformanceMonitor.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodOptionDecoratorInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodService.php, final class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskTypes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisk.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GroupDealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encoding, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encryption, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ES, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Faker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gecko, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gong, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Locks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Math, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Playlist, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Prophet, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Queue, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Router, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Saml2, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"SCIM, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Seeder, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sentry, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Serializer, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Settings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Slack, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Transcription, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dev","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dialers","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"role_description":"text"}]...
|
1311851641271176001
|
9055203785154560316
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats...
|
NULL
|
|
72875
|
1779
|
13
|
2026-04-23T06:20:45.430846+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-23/1776 /Users/lukas/.screenpipe/data/data/2026-04-23/1776925245430_m2.jpg...
|
PhpStorm
|
faVsco.js – UserTransformer.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.25731382,"top":0.019952115,"width":0.03856383,"height":0.025538707},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20157-AJ-report-not-send-notification, menu","depth":5,"bounds":{"left":0.29587767,"top":0.019952115,"width":0.10139628,"height":0.025538707},"help_text":"Git Branch: JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.7972075,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"bounds":{"left":0.8125,"top":0.019952115,"width":0.10305851,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"13","depth":4,"bounds":{"left":0.66921544,"top":0.15003991,"width":0.009640957,"height":0.015163607},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.68085104,"top":0.15003991,"width":0.007978723,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.69049203,"top":0.14844373,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.6978058,"top":0.14844373,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","depth":4,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"36","depth":4,"bounds":{"left":0.96210104,"top":0.10055866,"width":0.010305851,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.9740692,"top":0.09896249,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.98138297,"top":0.09896249,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.24335106,"top":0.047885075,"width":0.024268618,"height":0.024740623},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregator.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregatorInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatabaseActivities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatasourceInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivityInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Comments","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Forecast","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Jobs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"QueryBuilder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Services","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ClosingPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CreatedPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Criteria.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaNormalizer.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealContactService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsCriteriaBuilder.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepositoryInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsServiceRepositories.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PerformanceMonitor.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodOptionDecoratorInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodService.php, final class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskTypes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisk.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GroupDealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encoding, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encryption, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ES, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Faker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gecko, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gong, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Locks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Math, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Playlist, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Prophet, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Queue, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Router, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Saml2, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"SCIM, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Seeder, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sentry, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Serializer, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Settings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Slack, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Transcription, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dev","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dialers","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playlists","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Postmark","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Reports","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DeleteReportCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"GenerateMarketingReport.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Team.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Usage.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Teams","depth":10,"role_description":"text"}]...
|
11815614958514493
|
9055203785154560316
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams...
|
72874
|
|
72877
|
1779
|
14
|
2026-04-23T06:20:56.102087+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-23/1776 /Users/lukas/.screenpipe/data/data/2026-04-23/1776925256102_m2.jpg...
|
PhpStorm
|
faVsco.js – UserTransformer.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams
Tracks
Transcription
Twilio
Users
Vocabulary
Zoom
CoachingFeedbacksUpdateEsActivities.php, class
Command.php, class...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.25731382,"top":0.019952115,"width":0.03856383,"height":0.025538707},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20157-AJ-report-not-send-notification, menu","depth":5,"bounds":{"left":0.29587767,"top":0.019952115,"width":0.10139628,"height":0.025538707},"help_text":"Git Branch: JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.7972075,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"bounds":{"left":0.8125,"top":0.019952115,"width":0.10305851,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"13","depth":4,"bounds":{"left":0.66921544,"top":0.15003991,"width":0.009640957,"height":0.015163607},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.68085104,"top":0.15003991,"width":0.007978723,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.69049203,"top":0.14844373,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.6978058,"top":0.14844373,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","depth":4,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"36","depth":4,"bounds":{"left":0.96210104,"top":0.10055866,"width":0.010305851,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.9740692,"top":0.09896249,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.98138297,"top":0.09896249,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.24335106,"top":0.047885075,"width":0.024268618,"height":0.024740623},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregator.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregatorInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatabaseActivities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatasourceInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivityInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Comments","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Forecast","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Jobs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"QueryBuilder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Services","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ClosingPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CreatedPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Criteria.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaNormalizer.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealContactService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsCriteriaBuilder.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepositoryInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsServiceRepositories.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PerformanceMonitor.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodOptionDecoratorInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodService.php, final class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskTypes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisk.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GroupDealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encoding, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encryption, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ES, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Faker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gecko, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gong, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Locks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Math, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Playlist, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Prophet, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Queue, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Router, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Saml2, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"SCIM, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Seeder, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sentry, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Serializer, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Settings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Slack, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Transcription, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dev","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dialers","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playlists","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Postmark","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Reports","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DeleteReportCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"GenerateMarketingReport.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Team.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Usage.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Teams","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Tracks","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Twilio","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Users","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Vocabulary","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Zoom","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedbacksUpdateEsActivities.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Command.php, class","depth":10,"role_description":"text"}]...
|
-8441762177068411080
|
9055203785154560316
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams
Tracks
Transcription
Twilio
Users
Vocabulary
Zoom
CoachingFeedbacksUpdateEsActivities.php, class
Command.php, class...
|
NULL
|
|
72878
|
1778
|
11
|
2026-04-23T06:20:56.102062+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-23/1776 /Users/lukas/.screenpipe/data/data/2026-04-23/1776925256102_m1.jpg...
|
PhpStorm
|
faVsco.js – UserTransformer.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20157-AJ-report-not-send-notification, menu","depth":5,"help_text":"Git Branch: JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"13","depth":4,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","depth":4,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"36","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregator.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregatorInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatabaseActivities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatasourceInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivityInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Comments","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Forecast","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Jobs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"QueryBuilder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Services","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ClosingPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CreatedPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Criteria.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaNormalizer.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealContactService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsCriteriaBuilder.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepositoryInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsServiceRepositories.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PerformanceMonitor.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodOptionDecoratorInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodService.php, final class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskTypes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisk.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GroupDealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encoding, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encryption, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ES, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Faker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gecko, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gong, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Locks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Math, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Playlist, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Prophet, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Queue, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Router, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Saml2, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"SCIM, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Seeder, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sentry, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Serializer, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Settings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Slack, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Transcription, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dev","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dialers","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playlists","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Postmark","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Reports","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php, class","depth":11,"role_description":"text"}]...
|
-5846556723488841375
|
9055203785154560316
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class...
|
72876
|
|
72872
|
1779
|
11
|
2026-04-23T06:20:24.030966+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-23/1776 /Users/lukas/.screenpipe/data/data/2026-04-23/1776925224030_m2.jpg...
|
PhpStorm
|
faVsco.js – UserTransformer.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.25731382,"top":0.019952115,"width":0.03856383,"height":0.025538707},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20157-AJ-report-not-send-notification, menu","depth":5,"bounds":{"left":0.29587767,"top":0.019952115,"width":0.10139628,"height":0.025538707},"help_text":"Git Branch: JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.7972075,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"bounds":{"left":0.8125,"top":0.019952115,"width":0.10305851,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"13","depth":4,"bounds":{"left":0.66921544,"top":0.15003991,"width":0.009640957,"height":0.015163607},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.68085104,"top":0.15003991,"width":0.007978723,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.69049203,"top":0.14844373,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.6978058,"top":0.14844373,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","depth":4,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"36","depth":4,"bounds":{"left":0.96210104,"top":0.10055866,"width":0.010305851,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.9740692,"top":0.09896249,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.98138297,"top":0.09896249,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.24335106,"top":0.047885075,"width":0.024268618,"height":0.024740623},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregator.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregatorInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatabaseActivities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatasourceInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivityInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Comments","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Forecast","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Jobs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"QueryBuilder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Services","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ClosingPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CreatedPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Criteria.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaNormalizer.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealContactService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsCriteriaBuilder.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepositoryInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsServiceRepositories.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PerformanceMonitor.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodOptionDecoratorInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodService.php, final class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskTypes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisk.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GroupDealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encoding, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encryption, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ES, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Faker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gecko, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gong, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Locks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Math, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Playlist, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Prophet, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Queue, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Router, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Saml2, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"SCIM, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Seeder, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sentry, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Serializer, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Settings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Slack, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Transcription, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php, final class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php, abstract class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"role_description":"text"}]...
|
-8142214672847546299
|
9055203785154036012
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php, class
BullhornSessionCommand.php, class
CheckActivityLoggableCommand.php, final class
CleanDuplicateFieldDataCommand.php, class
FullSyncOpportunityCommand.php, class
LogActivitiesCommand.php, final class
ManageSyncStrategyCommand.php, class
MatchCrmObjectsCommand.php, class
MatchOpportunityActivitiesCommand.php, class
MigrateProvider.php, class
ProcessHubspotObjectsSyncBatches.php, class
PurgeDeletedOpportunitiesCommand.php, class
ResetGovernorLimits.php, class
SendNotLogged.php, class
SetupActivityTypeForFollowUp.php, final class
SetupCloseCrm.php, class
SetupCopperCrm.php, class
SetupCrmCommand.php, abstract class
SetupLayouts.php, class
SyncAccount.php, class
SyncContact.php, class
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class...
|
72870
|
|
19757
|
421
|
23
|
2026-04-15T07:58:40.105413+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-15/1776 /Users/lukas/.screenpipe/data/data/2026-04-15/1776239920105_m1.jpg...
|
Alfred
|
Alfred
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
k
|
[{"role":"AXTextField","text [{"role":"AXTextField","text":"k","depth":1,"bounds":{"left":0.26180556,"top":0.16777778,"width":0.4763889,"height":0.05888889},"value":"k","help_text":"Alfred Search","role_description":"text field","is_enabled":true,"is_focused":true}]...
|
9054207941445322226
|
9054207941445322226
|
visual_change
|
hybrid
|
NULL
|
k
SlackFileEditViewGoHistoryWindowHelpllol| [Platf k
SlackFileEditViewGoHistoryWindowHelpllol| [Platform] Planning... 2 m leftmeet.google.com/tgb-pyuf-dri?authuser=lukas.kovalik%40jiminny.comGalya Dimitrova (Presenting, annotating)SafariFileEditViewHistoryBookmarksDevelopA Sentry3 HubSpot|@ ОрeпA!|#i Seit Service# Platform Tes.88For youRecent# Starred89 Apps% Plans0 SpacesStarredJiminny (New)| II Platform TeamIID Processing TeamIID SE KanbanIID Capture TeamШD Enterprise Stability I...DiscoveryProductRecent4 Service-Desk= More spaces= FiltersSearchAWS USAWS EU7 A Journey tr.Start Sprint83 Features Ad.E Ask Sminey -Spaces / Jiminny (New)Platform Team88® Summary& TimelineWork items JY-20586, JY-20550, JY-20567, JY-20568 and 5 others do nothave a value for the 'Estimate' field. Values entered after the start of thesprint will be treated as scope change.Search backlog15 work items will be included in this sprint.Required fields are marked with an asterisk •Sprint name *Platform Sprint 2 Q2• v Platform Sprint 2 €2 weeksA JY-18909[PaStart date *© JY-19798 EvaA JY-20553 Del15/04/202610:56Planned start date: 15/04/2026, 01:00A sprint's start date impacts velocity and scope in reports. Learn more, (?End date *A JY-20632Pre01:00 |A JY-20489RevD JY-9712Chan© JY-20564 InwSprint goalLaunch AJ Panorama Reports for Jiminny usersOptimise nudges - lower the resources they need for executionN JY-20372 AIFA JY-20157 Sen1 LLM Evaluat• UpgradeAsk Rovo•8B List& Forms• ComponentsMore 9++29.59Start sprintIN DEV VCODE REVIEW1IN DEV V2BUG FIXING VECTIVE AN.BACKLOGECTIVE AN...BACKLOGREADY FOR DEVBACKLOG=Cancel|Stak2IB DashboardsA JY-20508 NotBACKLOG1OperationsC JY-20278AJ Panorama> Don't show internal errors to customersASK ANYTHING ON A..& CustomersBACKLOGmeet.google.com is sharing your screen.Stop sharing10:58 AM | [Platform] Planning | Session zSộ3•)).100% C8• Wed 15 Apr 10:58:399Stefka StoyanovaGalya Dimitrova4 othersNikolay NikoloyLukas Kovalik58:26...
|
NULL
|
|
76324
|
1910
|
32
|
2026-04-24T07:41:48.303337+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-24/1777 /Users/lukas/.screenpipe/data/data/2026-04-24/1777016508303_m2.jpg...
|
Firefox
|
Coverage on New Code - app in Jiminny SonarQube Cl Coverage on New Code - app in Jiminny SonarQube Cloud — Work...
|
1
|
sonarcloud.io/component_measures?metric=new_covera sonarcloud.io/component_measures?metric=new_coverage&selected=jiminny_app%3Aapp%2FJobs%2FAutomatedReports%2FSendReportNotGeneratedMailJob.php&view=list&pullRequest=12011&id=jiminny_app...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20489 | Optimize Nudges - Phase 2 by yalokin-jiminny · Pull Request #11997 · jiminny/app
JY-20489 | Optimize Nudges - Phase 2 by yalokin-jiminny · Pull Request #11997 · jiminny/app
New Tab
New Tab
AI reports promotion pages by nikolay-yankov · Pull Request #11998 · jiminny/app
AI reports promotion pages by nikolay-yankov · Pull Request #11998 · jiminny/app
JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app
JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app
Jiminny
Jiminny
Userpilot | Nudge-created
Userpilot | Nudge-created
Coverage on New Code - app in Jiminny SonarQube Cloud
Coverage on New Code - app in Jiminny SonarQube Cloud
Close tab
Pipelines - jiminny/app
Pipelines - jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to measure filters
Skip to measure filters
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture New
Architecture
New
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture New
Intended architecture
New
Project
Pull Requests 154
Pull Requests
154
Branches 16
Branches
16
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Measures
Measures
Measures
12011 – JY-20157 add not enough activities notification
12011 – JY-20157 add not enough activities notification
Project Overview
Security Domain help tooltip
Security
Reliability Domain help tooltip
Reliability
Maintainability Domain help tooltip
Maintainability
Security Review Domain help tooltip
Security Review
Coverage
Coverage
Coverage Has value: 6.3%
Coverage
6.3%
Lines to Cover Has value: 32
Lines to Cover
32
Uncovered Lines Has value: 30
Uncovered Lines
30
Line Coverage Has value: 6.3%
Line Coverage
6.3%
Conditions to Cover Has value: 0
Conditions to Cover
0
Uncovered Conditions Has value: 0
Uncovered Conditions
0
Duplications
Duplications
Size
Size
Issues
Issues
app
app
app
app
Jobs
Jobs
AutomatedReports
AutomatedReports
SendReportNotGeneratedMailJob.php
SendReportNotGeneratedMailJob.php
Copy to clipboard
Coverage on New Code
6.3%
Line: 1
Author: [EMAIL], Click to see SCM information
<?php
Line: 2
Author: [EMAIL], Click to see SCM information
Line: 3
Author: [EMAIL], Click to see SCM information
declare
(strict_types=
1
);
Line: 4
Author: [EMAIL], Click to see SCM information
Line: 5
Author: [EMAIL], Click to see SCM information
namespace
Jiminny\Jobs\AutomatedReports;
Line: 6
Author: [EMAIL], Click to see SCM information
Line: 7
Author: [EMAIL], Click to see SCM information
use
Illuminate\Bus\Queueable;
Line: 8
Author: [EMAIL], Click to see SCM information
use
Illuminate\Contracts\Queue\ShouldBeUnique;
Line: 9
Author: [EMAIL], Click to see SCM information
use
Illuminate\Contracts\Queue\ShouldQueue;
Line: 10
Author: [EMAIL], Click to see SCM information
use
Illuminate\Foundation\Bus\Dispatchable;
Line: 11
Author: [EMAIL], Click to see SCM information
use
Illuminate\Queue\InteractsWithQueue;
Line: 12
Author: [EMAIL], Click to see SCM information
use
Illuminate\Support\Facades\Mail;
Line: 13
Author: [EMAIL], Click to see SCM information
use
Jiminny\Component\Queue\Constants;
Line: 14
Author: [EMAIL], Click to see SCM information
use
Jiminny\Mail\Reports\ReportNotGenerated;
Line: 15
Author: [EMAIL], Click to see SCM information
use
Psr\Log\LoggerInterface;
Line: 16
Author: [EMAIL], Click to see SCM information
use
Sentry\Laravel\Facade
as
Sentry;
Line: 17
Author: [EMAIL], Click to see SCM information
use
Throwable;
Line: 18
Author: [EMAIL], Click to see SCM information
Line: 19
Author: [EMAIL], Click to see SCM information
class
SendReportNotGeneratedMailJob
implements
ShouldBeUnique, ShouldQueue
Line: 20
Author: [EMAIL], Click to see SCM information
{
Line: 21
Author: [EMAIL], Click to see SCM information
use
Dispatchable;
Line: 22
Author: [EMAIL], Click to see SCM information
use
InteractsWithQueue;
Line: 23
Author: [EMAIL], Click to see SCM information
use
Queueable;
Line: 24
Author: [EMAIL], Click to see SCM information
Line: 25
Author: [EMAIL], Click to see SCM information
private
const
string
LOG_PREFIX
=
'[Send Report Not Generated Mail]'
;
Line: 26
Author: [EMAIL], Click to see SCM information
Line: 27
Author: [EMAIL], Click to see SCM information
public
int
$tries
=
3
;
Line: 28
Author: [EMAIL], Click to see SCM information
Line: 29
Author: [EMAIL], Click to see SCM information
/**
Line: 30
Author: [EMAIL], Click to see SCM information
* @var array<int, int>
Line: 31
Author: [EMAIL], Click to see SCM information
*/
Line: 32
Author: [EMAIL], Click to see SCM information
public
array
$backoff
= [
60
,
300
,
600
];
Line: 33
Author: [EMAIL], Click to see SCM information
Line: 34
Author: [EMAIL], Click to see SCM information
public
int
$timeout
=
60
;
Line: 35
Author: [EMAIL], Click to see SCM information
Line: 36
Author: [EMAIL], Click to see SCM information
public
function
__construct
(
Line: 37
Author: [EMAIL], Click to see SCM information
private
readonly
string
$reportUuid
,
Line: 38
Author: [EMAIL], Click to see SCM information
private
readonly
string
$recipientEmail
,
Line: 39
Author: [EMAIL], Click to see SCM information
private
readonly
?string
$recipientName
,
Line: 40
Author: [EMAIL], Click to see SCM information
private
readonly
string
$reportName
,
Line: 41
Author: [EMAIL], Click to see SCM information
private
readonly
string
$periodName
,
Line: 42
Author: [EMAIL], Click to see SCM information
private
readonly
string
$reportsPageUrl
,
Line: 43
Author: [EMAIL], Click to see SCM information
) {
Line: 44
Author: [EMAIL], Click to see SCM information
$this
->onQueue(Constants::QUEUE_ANALYTICS_LOW);
Line: 45
Author: [EMAIL], Click to see SCM information
}
Line: 46
Author: [EMAIL], Click to see SCM information
Line: 47
Author: [EMAIL], Click to see SCM information
public
function
uniqueId
(): string
Line: 48
Author: [EMAIL], Click to see SCM information
{
Line: 49
Author: [EMAIL], Click to see SCM information
return
$this
->reportUuid .
'_not_generated_'
.
$this
->recipientEmail;
Line: 50
Author: [EMAIL], Click to see SCM information
}
Line: 51
Author: [EMAIL], Click to see SCM information
Line: 52
Author: [EMAIL], Click to see SCM information
public
function
handle
(LoggerInterface
$logger
): void
Line: 53
Author: [EMAIL], Click to see SCM information
{
Line: 54
Author: [EMAIL], Click to see SCM information
$mailSubject
=
"
Your '
{
$this
->reportName}
' report wasn't generated
"
;
Line: 55
Author: [EMAIL], Click to see SCM information
Line: 56
Author: [EMAIL], Click to see SCM information
try
{
Line: 57
Author: [EMAIL], Click to see SCM information
$mailable
=
new
ReportNotGenerated(
Line: 58
Author: [EMAIL], Click to see SCM information
reportName:
$this
->reportName,
Line: 59
Author: [EMAIL], Click to see SCM information
periodName:
$this
->periodName,
Line: 60
Author: [EMAIL], Click to see SCM information
reportsPageUrl:
$this
->reportsPageUrl,
Line: 61
Author: [EMAIL], Click to see SCM information
mailSubject:
$mailSubject
,
Line: 62
Author: [EMAIL], Click to see SCM information
);
Line: 63
Author: [EMAIL], Click to see SCM information
Line: 64
Author: [EMAIL], Click to see SCM information
Mail::mailer(
'postmark'
)
Line: 65
Author: [EMAIL], Click to see SCM information
->to(
$this
->recipientEmail)
Line: 66
Author: [EMAIL], Click to see SCM information
->send(
$mailable
);
Line: 67
Author: [EMAIL], Click to see SCM information
Line: 68
Author: [EMAIL], Click to see SCM information
$logger
->info(self::
LOG_PREFIX
.
' Email sent'
, [
Line: 69
Author: [EMAIL], Click to see SCM information
'uuid'
=>
$this
->reportUuid,
Line: 70
Author: [EMAIL], Click to see SCM information
'email'
=>
$this
->recipientEmail,
Line: 71
Author: [EMAIL], Click to see SCM information
'recipientName'
=>
$this
->recipientName,
Line: 72
Author: [EMAIL], Click to see SCM information
]);
Line: 73
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
}
catch
(Throwable
$e
) {
Line: 74
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
$logger
->error(self::
LOG_PREFIX
.
' Error sending email'
, [
Line: 75
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
'uuid'
=>
$this
->reportUuid,
Line: 76
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
'email'
=>
$this
->recipientEmail,
Line: 77
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
'error'
=>
$e
->getMessage(),
Line: 78
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
'trace'
=>
$e
->getTraceAsString(),
Line: 79
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
]);
Line: 80
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
Line: 81...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.23287898,"top":0.0518755,"width":0.07596409,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20489 | Optimize Nudges - Phase 2 by yalokin-jiminny · Pull Request #11997 · jiminny/app","depth":4,"bounds":{"left":0.23105054,"top":0.09497207,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20489 | Optimize Nudges - Phase 2 by yalokin-jiminny · Pull Request #11997 · jiminny/app","depth":5,"bounds":{"left":0.2443484,"top":0.10614525,"width":0.1619016,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.23105054,"top":0.12769353,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.2443484,"top":0.13886672,"width":0.014960106,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"AI reports promotion pages by nikolay-yankov · Pull Request #11998 · jiminny/app","depth":4,"bounds":{"left":0.23105054,"top":0.16041501,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AI reports promotion pages by nikolay-yankov · Pull Request #11998 · jiminny/app","depth":5,"bounds":{"left":0.2443484,"top":0.17158818,"width":0.14128989,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app","depth":4,"bounds":{"left":0.23105054,"top":0.19313647,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app","depth":5,"bounds":{"left":0.2443484,"top":0.20430966,"width":0.16555852,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.23105054,"top":0.22585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.2443484,"top":0.23703113,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Userpilot | Nudge-created","depth":4,"bounds":{"left":0.23105054,"top":0.2585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Userpilot | Nudge-created","depth":5,"bounds":{"left":0.2443484,"top":0.2697526,"width":0.04537899,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Coverage on New Code - app in Jiminny SonarQube Cloud","depth":4,"bounds":{"left":0.23105054,"top":0.29130086,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Coverage on New Code - app in Jiminny SonarQube Cloud","depth":5,"bounds":{"left":0.2443484,"top":0.30247405,"width":0.10139628,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.29837102,"top":0.29848364,"width":0.007978723,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.23105054,"top":0.32402235,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"bounds":{"left":0.2443484,"top":0.33519554,"width":0.039228722,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.23105054,"top":0.3567438,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.2443484,"top":0.367917,"width":0.15924202,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.23387633,"top":0.39106146,"width":0.07413564,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.23387633,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.24484707,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.25598404,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.26712102,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.27825797,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to main content","depth":7,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Skip to measure filters","depth":7,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to measure filters","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Undock sidebar","depth":8,"bounds":{"left":0.3146609,"top":0.059856344,"width":0.011968086,"height":0.028731046},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Continuous Code Quality","depth":8,"bounds":{"left":0.33460772,"top":0.058260176,"width":0.04936835,"height":0.031923383},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Favorite Projects","depth":11,"bounds":{"left":0.39594415,"top":0.061452515,"width":0.041888297,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Favorite Projects","depth":12,"bounds":{"left":0.39793882,"top":0.06743815,"width":0.037898935,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Assigned Issues","depth":11,"bounds":{"left":0.44049203,"top":0.061452515,"width":0.040724736,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Assigned Issues","depth":12,"bounds":{"left":0.4424867,"top":0.06743815,"width":0.03673537,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":11,"bounds":{"left":0.48387632,"top":0.061452515,"width":0.020944148,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":12,"bounds":{"left":0.48587102,"top":0.06743815,"width":0.016954787,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search","depth":8,"bounds":{"left":0.92785907,"top":0.061452515,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Product news","depth":8,"bounds":{"left":0.9411569,"top":0.061452515,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":10,"bounds":{"left":0.9478058,"top":0.06384677,"width":0.0019946808,"height":0.009976057},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":8,"bounds":{"left":0.9544548,"top":0.061452515,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New...","depth":8,"bounds":{"left":0.96775264,"top":0.061452515,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Account","depth":8,"bounds":{"left":0.98105055,"top":0.061452515,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app","depth":12,"bounds":{"left":0.32662898,"top":0.111332804,"width":0.008477394,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":11,"bounds":{"left":0.32662898,"top":0.1264964,"width":0.013297873,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":10,"bounds":{"left":0.31333113,"top":0.15881884,"width":0.07446808,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Overview","depth":12,"bounds":{"left":0.32396942,"top":0.16480447,"width":0.020777926,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Analysis","depth":13,"bounds":{"left":0.3159907,"top":0.19752593,"width":0.015791224,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Summary","depth":13,"bounds":{"left":0.31333113,"top":0.21947326,"width":0.07446808,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summary","depth":15,"bounds":{"left":0.32396942,"top":0.2254589,"width":0.020944148,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":13,"bounds":{"left":0.31333113,"top":0.2482043,"width":0.07446808,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":15,"bounds":{"left":0.32396942,"top":0.25418994,"width":0.01412899,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Architecture New","depth":13,"bounds":{"left":0.31333113,"top":0.27693537,"width":0.07446808,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Architecture","depth":15,"bounds":{"left":0.32396942,"top":0.282921,"width":0.026928192,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"New","depth":15,"bounds":{"left":0.37516624,"top":0.28371906,"width":0.008643617,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security hotspots","depth":13,"bounds":{"left":0.31333113,"top":0.3056664,"width":0.07446808,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security hotspots","depth":15,"bounds":{"left":0.32396942,"top":0.31165203,"width":0.03856383,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Reporting","depth":13,"bounds":{"left":0.3159907,"top":0.3443735,"width":0.018284574,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Measures","depth":13,"bounds":{"left":0.31333113,"top":0.36632082,"width":0.07446808,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Measures","depth":15,"bounds":{"left":0.32396942,"top":0.37230647,"width":0.022273935,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Activity","depth":13,"bounds":{"left":0.31333113,"top":0.39505187,"width":0.07446808,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":15,"bounds":{"left":0.32396942,"top":0.4010375,"width":0.016456118,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Policies","depth":13,"bounds":{"left":0.3159907,"top":0.43375897,"width":0.014461436,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Intended architecture New","depth":13,"bounds":{"left":0.31333113,"top":0.4557063,"width":0.07446808,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Intended architecture","depth":15,"bounds":{"left":0.32396942,"top":0.46169195,"width":0.047041222,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"New","depth":15,"bounds":{"left":0.37516624,"top":0.46249002,"width":0.008643617,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":13,"bounds":{"left":0.3159907,"top":0.4944134,"width":0.013297873,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull Requests 154","depth":13,"bounds":{"left":0.31333113,"top":0.51636076,"width":0.07446808,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull Requests","depth":15,"bounds":{"left":0.32396942,"top":0.5223464,"width":0.029587766,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"154","depth":15,"bounds":{"left":0.37699467,"top":0.5231444,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Branches 16","depth":13,"bounds":{"left":0.31333113,"top":0.5450918,"width":0.07446808,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Branches","depth":15,"bounds":{"left":0.32396942,"top":0.5510774,"width":0.020777926,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16","depth":15,"bounds":{"left":0.37965426,"top":0.5518755,"width":0.004155585,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":13,"bounds":{"left":0.31333113,"top":0.5738228,"width":0.07446808,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":15,"bounds":{"left":0.32396942,"top":0.5798085,"width":0.011801862,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Project Information","depth":13,"bounds":{"left":0.31333113,"top":0.60255384,"width":0.07446808,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Project Information","depth":15,"bounds":{"left":0.32396942,"top":0.6085395,"width":0.041888297,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny","depth":9,"bounds":{"left":0.39876994,"top":0.11691939,"width":0.01462766,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":10,"bounds":{"left":0.39876994,"top":0.11691939,"width":0.01462766,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":9,"bounds":{"left":0.42270613,"top":0.11691939,"width":0.0071476065,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":10,"bounds":{"left":0.42270613,"top":0.11691939,"width":0.0071476065,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Measures","depth":9,"bounds":{"left":0.43916222,"top":0.11691939,"width":0.018450798,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Measures","depth":8,"bounds":{"left":0.39876994,"top":0.14205906,"width":0.03673537,"height":0.028731046},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Measures","depth":9,"bounds":{"left":0.39876994,"top":0.14485236,"width":0.03673537,"height":0.023543496},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12011 – JY-20157 add not enough activities notification","depth":8,"bounds":{"left":0.44348404,"top":0.14365523,"width":0.13297872,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12011 – JY-20157 add not enough activities notification","depth":11,"bounds":{"left":0.45462102,"top":0.14964086,"width":0.122340426,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Project Overview","depth":8,"bounds":{"left":0.3977726,"top":0.22027135,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Security Domain help tooltip","depth":9,"bounds":{"left":0.3977726,"top":0.27613726,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Security","depth":11,"bounds":{"left":0.40309176,"top":0.29010376,"width":0.018949468,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reliability Domain help tooltip","depth":9,"bounds":{"left":0.3977726,"top":0.3320032,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reliability","depth":11,"bounds":{"left":0.40309176,"top":0.34596968,"width":0.021941489,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Maintainability Domain help tooltip","depth":9,"bounds":{"left":0.3977726,"top":0.38786912,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Maintainability","depth":11,"bounds":{"left":0.40309176,"top":0.4018356,"width":0.03307846,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Security Review Domain help tooltip","depth":9,"bounds":{"left":0.3977726,"top":0.44373503,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Security Review","depth":11,"bounds":{"left":0.40309176,"top":0.4577015,"width":0.036236703,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Coverage","depth":9,"bounds":{"left":0.3977726,"top":0.49960095,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Coverage","depth":11,"bounds":{"left":0.40309176,"top":0.51356745,"width":0.021775266,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Coverage Has value: 6.3%","depth":9,"bounds":{"left":0.3977726,"top":0.54269755,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Coverage","depth":11,"bounds":{"left":0.40575132,"top":0.556664,"width":0.021276595,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6.3%","depth":11,"bounds":{"left":0.46509308,"top":0.556664,"width":0.011469414,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Lines to Cover Has value: 32","depth":9,"bounds":{"left":0.3977726,"top":0.584996,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lines to Cover","depth":11,"bounds":{"left":0.40575132,"top":0.5989625,"width":0.03158245,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"32","depth":11,"bounds":{"left":0.4709109,"top":0.5989625,"width":0.0056515955,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Uncovered Lines Has value: 30","depth":9,"bounds":{"left":0.3977726,"top":0.6272945,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Uncovered Lines","depth":11,"bounds":{"left":0.40575132,"top":0.641261,"width":0.03706782,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":11,"bounds":{"left":0.47074467,"top":0.641261,"width":0.005817819,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line Coverage Has value: 6.3%","depth":9,"bounds":{"left":0.3977726,"top":0.669593,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Line Coverage","depth":11,"bounds":{"left":0.40575132,"top":0.6835595,"width":0.03174867,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6.3%","depth":11,"bounds":{"left":0.46509308,"top":0.6835595,"width":0.011469414,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Conditions to Cover Has value: 0","depth":9,"bounds":{"left":0.3977726,"top":0.7118915,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Conditions to Cover","depth":11,"bounds":{"left":0.40575132,"top":0.7258579,"width":0.043550532,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":11,"bounds":{"left":0.47357047,"top":0.7258579,"width":0.0029920214,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Uncovered Conditions Has value: 0","depth":9,"bounds":{"left":0.3977726,"top":0.75418997,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Uncovered Conditions","depth":11,"bounds":{"left":0.40575132,"top":0.7681564,"width":0.04886968,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":11,"bounds":{"left":0.47357047,"top":0.7681564,"width":0.0029920214,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Duplications","depth":9,"bounds":{"left":0.3977726,"top":0.81005585,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Duplications","depth":11,"bounds":{"left":0.40309176,"top":0.82402235,"width":0.028091755,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Size","depth":9,"bounds":{"left":0.3977726,"top":0.8659218,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Size","depth":11,"bounds":{"left":0.40309176,"top":0.8798883,"width":0.009474734,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Issues","depth":9,"bounds":{"left":0.3977726,"top":0.92178774,"width":0.08543883,"height":0.0415004},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Issues","depth":11,"bounds":{"left":0.40309176,"top":0.9357542,"width":0.01462766,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.56865025,"top":0.22944932,"width":0.008477394,"height":0.01396648},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":13,"bounds":{"left":0.56865025,"top":0.22944932,"width":0.008477394,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.5824468,"top":0.22944932,"width":0.008477394,"height":0.01396648},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":13,"bounds":{"left":0.5824468,"top":0.22944932,"width":0.008477394,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jobs","depth":12,"bounds":{"left":0.5962433,"top":0.22944932,"width":0.010970744,"height":0.01396648},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jobs","depth":13,"bounds":{"left":0.5962433,"top":0.22944932,"width":0.010970744,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"AutomatedReports","depth":12,"bounds":{"left":0.6125333,"top":0.22944932,"width":0.042220745,"height":0.01396648},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AutomatedReports","depth":13,"bounds":{"left":0.6125333,"top":0.22944932,"width":0.042220745,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SendReportNotGeneratedMailJob.php","depth":12,"bounds":{"left":0.66007316,"top":0.22944932,"width":0.08610372,"height":0.01396648},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SendReportNotGeneratedMailJob.php","depth":13,"bounds":{"left":0.66007316,"top":0.22944932,"width":0.08610372,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy to clipboard","depth":10,"bounds":{"left":0.75016624,"top":0.22346368,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Coverage on New Code","depth":12,"bounds":{"left":0.56865025,"top":0.28371906,"width":0.06050532,"height":0.01556265},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6.3%","depth":12,"bounds":{"left":0.63048536,"top":0.28371906,"width":0.012965426,"height":0.01556265},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 1","depth":12,"bounds":{"left":0.5716423,"top":0.32083002,"width":0.004986702,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.32083002,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"<?php","depth":14,"bounds":{"left":0.6171875,"top":0.32322428,"width":0.011635638,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 2","depth":12,"bounds":{"left":0.5716423,"top":0.3367917,"width":0.004986702,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.3367917,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 3","depth":12,"bounds":{"left":0.5716423,"top":0.3527534,"width":0.004986702,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.3527534,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"declare","depth":14,"bounds":{"left":0.6171875,"top":0.35514766,"width":0.016289894,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(strict_types=","depth":14,"bounds":{"left":0.6334774,"top":0.35514766,"width":0.032579787,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":14,"bounds":{"left":0.66605717,"top":0.35514766,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":14,"bounds":{"left":0.6683843,"top":0.35514766,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 4","depth":12,"bounds":{"left":0.5716423,"top":0.36871508,"width":0.004986702,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.36871508,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 5","depth":12,"bounds":{"left":0.5716423,"top":0.38467678,"width":0.004986702,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.38467678,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"namespace","depth":14,"bounds":{"left":0.6171875,"top":0.38707104,"width":0.020944148,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Jobs\\AutomatedReports;","depth":14,"bounds":{"left":0.6381317,"top":0.38707104,"width":0.072140954,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 6","depth":12,"bounds":{"left":0.5716423,"top":0.40063846,"width":0.004986702,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.40063846,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 7","depth":12,"bounds":{"left":0.5716423,"top":0.41660017,"width":0.004986702,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.41660017,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.6171875,"top":0.41899443,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Bus\\Queueable;","depth":14,"bounds":{"left":0.6241689,"top":0.41899443,"width":0.06050532,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 8","depth":12,"bounds":{"left":0.5716423,"top":0.43256184,"width":0.004986702,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.43256184,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.6171875,"top":0.4349561,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Contracts\\Queue\\ShouldBeUnique;","depth":14,"bounds":{"left":0.6241689,"top":0.4349561,"width":0.10006649,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 9","depth":12,"bounds":{"left":0.5716423,"top":0.44852355,"width":0.004986702,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.44852355,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.6171875,"top":0.4509178,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Contracts\\Queue\\ShouldQueue;","depth":14,"bounds":{"left":0.6241689,"top":0.4509178,"width":0.0930851,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 10","depth":12,"bounds":{"left":0.5716423,"top":0.46448523,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.46448523,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.6171875,"top":0.4668795,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Foundation\\Bus\\Dispatchable;","depth":14,"bounds":{"left":0.6241689,"top":0.4668795,"width":0.0930851,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 11","depth":12,"bounds":{"left":0.5716423,"top":0.48044693,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.48044693,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.6171875,"top":0.4828412,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Queue\\InteractsWithQueue;","depth":14,"bounds":{"left":0.6241689,"top":0.4828412,"width":0.08610372,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 12","depth":12,"bounds":{"left":0.5716423,"top":0.4964086,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.4964086,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.6171875,"top":0.49880287,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Support\\Facades\\Mail;","depth":14,"bounds":{"left":0.6241689,"top":0.49880287,"width":0.07679521,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 13","depth":12,"bounds":{"left":0.5716423,"top":0.5123703,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.5123703,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.6171875,"top":0.51476455,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Component\\Queue\\Constants;","depth":14,"bounds":{"left":0.6241689,"top":0.51476455,"width":0.08144947,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 14","depth":12,"bounds":{"left":0.5716423,"top":0.528332,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.528332,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.6171875,"top":0.53072625,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Mail\\Reports\\ReportNotGenerated;","depth":14,"bounds":{"left":0.6241689,"top":0.53072625,"width":0.09541223,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 15","depth":12,"bounds":{"left":0.5716423,"top":0.5442937,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.5442937,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.6171875,"top":0.54668796,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Psr\\Log\\LoggerInterface;","depth":14,"bounds":{"left":0.6241689,"top":0.54668796,"width":0.05817819,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 16","depth":12,"bounds":{"left":0.5716423,"top":0.5602554,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.5602554,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.6171875,"top":0.56264967,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sentry\\Laravel\\Facade","depth":14,"bounds":{"left":0.6241689,"top":0.56264967,"width":0.053523935,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"as","depth":14,"bounds":{"left":0.67769283,"top":0.56264967,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sentry;","depth":14,"bounds":{"left":0.68234706,"top":0.56264967,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 17","depth":12,"bounds":{"left":0.5716423,"top":0.57621706,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.57621706,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.6171875,"top":0.5786113,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Throwable;","depth":14,"bounds":{"left":0.6241689,"top":0.5786113,"width":0.025598405,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 18","depth":12,"bounds":{"left":0.5716423,"top":0.59217876,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.59217876,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 19","depth":12,"bounds":{"left":0.5716423,"top":0.60814047,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.60814047,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"class","depth":14,"bounds":{"left":0.6171875,"top":0.6105347,"width":0.011635638,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SendReportNotGeneratedMailJob","depth":14,"bounds":{"left":0.63115025,"top":0.6105347,"width":0.0674867,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"implements","depth":14,"bounds":{"left":0.7009641,"top":0.6105347,"width":0.023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ShouldBeUnique, ShouldQueue","depth":14,"bounds":{"left":0.72423536,"top":0.6105347,"width":0.065159574,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 20","depth":12,"bounds":{"left":0.5716423,"top":0.6241022,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.6241022,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"{","depth":14,"bounds":{"left":0.6171875,"top":0.62649643,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 21","depth":12,"bounds":{"left":0.5716423,"top":0.6400638,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.6400638,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.626496,"top":0.6424581,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dispatchable;","depth":14,"bounds":{"left":0.6334774,"top":0.6424581,"width":0.032579787,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 22","depth":12,"bounds":{"left":0.5716423,"top":0.6560255,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.6560255,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.626496,"top":0.6584198,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"InteractsWithQueue;","depth":14,"bounds":{"left":0.6334774,"top":0.6584198,"width":0.04654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 23","depth":12,"bounds":{"left":0.5716423,"top":0.67198724,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.67198724,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"bounds":{"left":0.626496,"top":0.6743815,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Queueable;","depth":14,"bounds":{"left":0.6334774,"top":0.6743815,"width":0.025598405,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 24","depth":12,"bounds":{"left":0.5716423,"top":0.68794894,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.68794894,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 25","depth":12,"bounds":{"left":0.5716423,"top":0.7039106,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.7039106,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"bounds":{"left":0.626496,"top":0.70630485,"width":0.016289894,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"const","depth":14,"bounds":{"left":0.64511305,"top":0.70630485,"width":0.011635638,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":14,"bounds":{"left":0.65674865,"top":0.70630485,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"LOG_PREFIX","depth":14,"bounds":{"left":0.6753657,"top":0.70630485,"width":0.023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":14,"bounds":{"left":0.69863695,"top":0.70630485,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'[Send Report Not Generated Mail]'","depth":14,"bounds":{"left":0.7056183,"top":0.70630485,"width":0.07912234,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":14,"bounds":{"left":0.7847407,"top":0.70630485,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 26","depth":12,"bounds":{"left":0.5716423,"top":0.7198723,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.7198723,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 27","depth":12,"bounds":{"left":0.5716423,"top":0.735834,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.735834,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":14,"bounds":{"left":0.626496,"top":0.73822826,"width":0.013962766,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"int","depth":14,"bounds":{"left":0.64045876,"top":0.73822826,"width":0.011635638,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$tries","depth":14,"bounds":{"left":0.6520944,"top":0.73822826,"width":0.013962766,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":14,"bounds":{"left":0.66605717,"top":0.73822826,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3","depth":14,"bounds":{"left":0.67303854,"top":0.73822826,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":14,"bounds":{"left":0.6753657,"top":0.73822826,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 28","depth":12,"bounds":{"left":0.5716423,"top":0.7517957,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.7517957,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 29","depth":12,"bounds":{"left":0.5716423,"top":0.76775736,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.76775736,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"/**","depth":14,"bounds":{"left":0.626496,"top":0.7701516,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 30","depth":12,"bounds":{"left":0.5716423,"top":0.78371906,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.78371906,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"* @var array<int, int>","depth":14,"bounds":{"left":0.6171875,"top":0.7861133,"width":0.062832445,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 31","depth":12,"bounds":{"left":0.5716423,"top":0.79968077,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.79968077,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"*/","depth":14,"bounds":{"left":0.6171875,"top":0.802075,"width":0.016289894,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 32","depth":12,"bounds":{"left":0.5716423,"top":0.8156425,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.8156425,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":14,"bounds":{"left":0.626496,"top":0.81803674,"width":0.013962766,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"array","depth":14,"bounds":{"left":0.6427859,"top":0.81803674,"width":0.011635638,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$backoff","depth":14,"bounds":{"left":0.65674865,"top":0.81803674,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"= [","depth":14,"bounds":{"left":0.6753657,"top":0.81803674,"width":0.00930851,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"60","depth":14,"bounds":{"left":0.6846742,"top":0.81803674,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.68932843,"top":0.81803674,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"300","depth":14,"bounds":{"left":0.6939827,"top":0.81803674,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.7009641,"top":0.81803674,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"600","depth":14,"bounds":{"left":0.7056183,"top":0.81803674,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"];","depth":14,"bounds":{"left":0.71259975,"top":0.81803674,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 33","depth":12,"bounds":{"left":0.5716423,"top":0.8316041,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.8316041,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 34","depth":12,"bounds":{"left":0.5716423,"top":0.8475658,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.8475658,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":14,"bounds":{"left":0.626496,"top":0.8499601,"width":0.013962766,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"int","depth":14,"bounds":{"left":0.64045876,"top":0.8499601,"width":0.011635638,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$timeout","depth":14,"bounds":{"left":0.6520944,"top":0.8499601,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":14,"bounds":{"left":0.67071146,"top":0.8499601,"width":0.006981383,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"60","depth":14,"bounds":{"left":0.67769283,"top":0.8499601,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":14,"bounds":{"left":0.68234706,"top":0.8499601,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 35","depth":12,"bounds":{"left":0.5716423,"top":0.86352754,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.86352754,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 36","depth":12,"bounds":{"left":0.5716423,"top":0.87948924,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.87948924,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":14,"bounds":{"left":0.626496,"top":0.8818835,"width":0.013962766,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":14,"bounds":{"left":0.6427859,"top":0.8818835,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"__construct","depth":14,"bounds":{"left":0.66373,"top":0.8818835,"width":0.025598405,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.68932843,"top":0.8818835,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 37","depth":12,"bounds":{"left":0.5716423,"top":0.8954509,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.8954509,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"bounds":{"left":0.63580453,"top":0.89784515,"width":0.016289894,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"readonly","depth":14,"bounds":{"left":0.65442157,"top":0.89784515,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":14,"bounds":{"left":0.67303854,"top":0.89784515,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$reportUuid","depth":14,"bounds":{"left":0.6916556,"top":0.89784515,"width":0.025598405,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.717254,"top":0.89784515,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 38","depth":12,"bounds":{"left":0.5716423,"top":0.9114126,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.9114126,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"bounds":{"left":0.63580453,"top":0.91380686,"width":0.016289894,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"readonly","depth":14,"bounds":{"left":0.65442157,"top":0.91380686,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":14,"bounds":{"left":0.67303854,"top":0.91380686,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$recipientEmail","depth":14,"bounds":{"left":0.6916556,"top":0.91380686,"width":0.034906916,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.7265625,"top":0.91380686,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 39","depth":12,"bounds":{"left":0.5716423,"top":0.9273743,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.9273743,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"bounds":{"left":0.63580453,"top":0.92976856,"width":0.016289894,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"readonly","depth":14,"bounds":{"left":0.65442157,"top":0.92976856,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"?string","depth":14,"bounds":{"left":0.67303854,"top":0.92976856,"width":0.020944148,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$recipientName","depth":14,"bounds":{"left":0.6939827,"top":0.92976856,"width":0.032579787,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.7265625,"top":0.92976856,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 40","depth":12,"bounds":{"left":0.5716423,"top":0.943336,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.943336,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"bounds":{"left":0.63580453,"top":0.94573027,"width":0.016289894,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"readonly","depth":14,"bounds":{"left":0.65442157,"top":0.94573027,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":14,"bounds":{"left":0.67303854,"top":0.94573027,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$reportName","depth":14,"bounds":{"left":0.6916556,"top":0.94573027,"width":0.025598405,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.717254,"top":0.94573027,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 41","depth":12,"bounds":{"left":0.5716423,"top":0.95929766,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.95929766,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"bounds":{"left":0.63580453,"top":0.9616919,"width":0.016289894,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"readonly","depth":14,"bounds":{"left":0.65442157,"top":0.9616919,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":14,"bounds":{"left":0.67303854,"top":0.9616919,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$periodName","depth":14,"bounds":{"left":0.6916556,"top":0.9616919,"width":0.025598405,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.717254,"top":0.9616919,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 42","depth":12,"bounds":{"left":0.5716423,"top":0.97525936,"width":0.00731383,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.97525936,"width":0.019281914,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"bounds":{"left":0.63580453,"top":0.9776536,"width":0.016289894,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"readonly","depth":14,"bounds":{"left":0.65442157,"top":0.9776536,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":14,"bounds":{"left":0.67303854,"top":0.9776536,"width":0.01861702,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$reportsPageUrl","depth":14,"bounds":{"left":0.6916556,"top":0.9776536,"width":0.034906916,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.7265625,"top":0.9776536,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 43","depth":12,"bounds":{"left":0.5716423,"top":0.9912211,"width":0.00731383,"height":0.00877893},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":0.9912211,"width":0.019281914,"height":0.00877893},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":") {","depth":14,"bounds":{"left":0.6171875,"top":0.9936153,"width":0.016289894,"height":0.0063846707},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 44","depth":12,"bounds":{"left":0.5716423,"top":1.0,"width":0.00731383,"height":-0.0071827173},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":1.0,"width":0.019281914,"height":-0.0071827173},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"$this","depth":14,"bounds":{"left":0.63580453,"top":1.0,"width":0.011635638,"height":-0.009577036},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->onQueue(Constants::QUEUE_ANALYTICS_LOW);","depth":14,"bounds":{"left":0.64744014,"top":1.0,"width":0.09773936,"height":-0.009577036},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 45","depth":12,"bounds":{"left":0.5716423,"top":1.0,"width":0.00731383,"height":-0.023144484},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":1.0,"width":0.019281914,"height":-0.023144484},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"}","depth":14,"bounds":{"left":0.6171875,"top":1.0,"width":0.011635638,"height":-0.025538683},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 46","depth":12,"bounds":{"left":0.5716423,"top":1.0,"width":0.00731383,"height":-0.03910613},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":1.0,"width":0.019281914,"height":-0.03910613},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 47","depth":12,"bounds":{"left":0.5716423,"top":1.0,"width":0.00731383,"height":-0.055067778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":1.0,"width":0.019281914,"height":-0.055067778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":14,"bounds":{"left":0.626496,"top":1.0,"width":0.013962766,"height":-0.057462096},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":14,"bounds":{"left":0.6427859,"top":1.0,"width":0.01861702,"height":-0.057462096},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"uniqueId","depth":14,"bounds":{"left":0.66373,"top":1.0,"width":0.01861702,"height":-0.057462096},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(): string","depth":14,"bounds":{"left":0.68234706,"top":1.0,"width":0.023271276,"height":-0.057462096},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 48","depth":12,"bounds":{"left":0.5716423,"top":1.0,"width":0.00731383,"height":-0.071029544},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":1.0,"width":0.019281914,"height":-0.071029544},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"{","depth":14,"bounds":{"left":0.6171875,"top":1.0,"width":0.011635638,"height":-0.07342374},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 49","depth":12,"bounds":{"left":0.5716423,"top":1.0,"width":0.00731383,"height":-0.08699119},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.58361036,"top":1.0,"width":0.019281914,"height":-0.08699119},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"return","depth":14,"bounds":{"left":0.63580453,"top":1.0,"width":0.013962766,"height":-0.08938551},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"bounds":{"left":0.6520944,"top":1.0,"width":0.011635638,"height":-0.08938551},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->reportUuid .","depth":14,"bounds":{"left":0.66373,"top":1.0,"width":0.034906916,"height":-0.08938551},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'_not_generated_'","depth":14,"bounds":{"left":0.69863695,"top":1.0,"width":0.03956117,"height":-0.08938551},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":14,"bounds":{"left":0.73819816,"top":1.0,"width":0.006981383,"height":-0.08938551},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"bounds":{"left":0.74517953,"top":1.0,"width":0.011635638,"height":-0.08938551},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->recipientEmail;","depth":14,"bounds":{"left":0.75681514,"top":1.0,"width":0.03956117,"height":-0.08938551},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 50","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"}","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 51","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 52","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"handle","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(LoggerInterface","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$logger","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"): void","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 53","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"{","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 54","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"$mailSubject","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your '","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"{","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->reportName}","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"' report wasn't generated","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 55","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 56","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"try","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"{","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 57","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"$mailable","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"new","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ReportNotGenerated(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 58","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"reportName:","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->reportName,","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 59","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"periodName:","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->periodName,","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 60","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"reportsPageUrl:","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->reportsPageUrl,","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 61","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"mailSubject:","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$mailSubject","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 62","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":");","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 63","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 64","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Mail::mailer(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'postmark'","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 65","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"->to(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->recipientEmail)","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 66","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"->send(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$mailable","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 67","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 68","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"$logger","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->info(self::","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"LOG_PREFIX","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"' Email sent'","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", [","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 69","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"'uuid'","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=>","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->reportUuid,","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 70","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"'email'","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=>","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->recipientEmail,","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 71","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"'recipientName'","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=>","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->recipientName,","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 72","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"]);","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 73","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Duplicated block. Click for details.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"}","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"catch","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(Throwable","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$e","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") {","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 74","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Duplicated block. Click for details.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"$logger","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->error(self::","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"LOG_PREFIX","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"' Error sending email'","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", [","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 75","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Duplicated block. Click for details.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"'uuid'","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=>","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->reportUuid,","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 76","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Duplicated block. Click for details.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"'email'","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=>","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->recipientEmail,","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 77","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Duplicated block. Click for details.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"'error'","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=>","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$e","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->getMessage(),","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 78","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Duplicated block. Click for details.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"'trace'","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=>","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$e","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->getTraceAsString(),","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 79","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Duplicated block. Click for details.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"]);","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 80","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Duplicated block. Click for details.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Line: 81","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-8517634898903502995
|
9040408162237327162
|
idle
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20489 | Optimize Nudges - Phase 2 by yalokin-jiminny · Pull Request #11997 · jiminny/app
JY-20489 | Optimize Nudges - Phase 2 by yalokin-jiminny · Pull Request #11997 · jiminny/app
New Tab
New Tab
AI reports promotion pages by nikolay-yankov · Pull Request #11998 · jiminny/app
AI reports promotion pages by nikolay-yankov · Pull Request #11998 · jiminny/app
JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app
JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app
Jiminny
Jiminny
Userpilot | Nudge-created
Userpilot | Nudge-created
Coverage on New Code - app in Jiminny SonarQube Cloud
Coverage on New Code - app in Jiminny SonarQube Cloud
Close tab
Pipelines - jiminny/app
Pipelines - jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to measure filters
Skip to measure filters
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture New
Architecture
New
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture New
Intended architecture
New
Project
Pull Requests 154
Pull Requests
154
Branches 16
Branches
16
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Measures
Measures
Measures
12011 – JY-20157 add not enough activities notification
12011 – JY-20157 add not enough activities notification
Project Overview
Security Domain help tooltip
Security
Reliability Domain help tooltip
Reliability
Maintainability Domain help tooltip
Maintainability
Security Review Domain help tooltip
Security Review
Coverage
Coverage
Coverage Has value: 6.3%
Coverage
6.3%
Lines to Cover Has value: 32
Lines to Cover
32
Uncovered Lines Has value: 30
Uncovered Lines
30
Line Coverage Has value: 6.3%
Line Coverage
6.3%
Conditions to Cover Has value: 0
Conditions to Cover
0
Uncovered Conditions Has value: 0
Uncovered Conditions
0
Duplications
Duplications
Size
Size
Issues
Issues
app
app
app
app
Jobs
Jobs
AutomatedReports
AutomatedReports
SendReportNotGeneratedMailJob.php
SendReportNotGeneratedMailJob.php
Copy to clipboard
Coverage on New Code
6.3%
Line: 1
Author: [EMAIL], Click to see SCM information
<?php
Line: 2
Author: [EMAIL], Click to see SCM information
Line: 3
Author: [EMAIL], Click to see SCM information
declare
(strict_types=
1
);
Line: 4
Author: [EMAIL], Click to see SCM information
Line: 5
Author: [EMAIL], Click to see SCM information
namespace
Jiminny\Jobs\AutomatedReports;
Line: 6
Author: [EMAIL], Click to see SCM information
Line: 7
Author: [EMAIL], Click to see SCM information
use
Illuminate\Bus\Queueable;
Line: 8
Author: [EMAIL], Click to see SCM information
use
Illuminate\Contracts\Queue\ShouldBeUnique;
Line: 9
Author: [EMAIL], Click to see SCM information
use
Illuminate\Contracts\Queue\ShouldQueue;
Line: 10
Author: [EMAIL], Click to see SCM information
use
Illuminate\Foundation\Bus\Dispatchable;
Line: 11
Author: [EMAIL], Click to see SCM information
use
Illuminate\Queue\InteractsWithQueue;
Line: 12
Author: [EMAIL], Click to see SCM information
use
Illuminate\Support\Facades\Mail;
Line: 13
Author: [EMAIL], Click to see SCM information
use
Jiminny\Component\Queue\Constants;
Line: 14
Author: [EMAIL], Click to see SCM information
use
Jiminny\Mail\Reports\ReportNotGenerated;
Line: 15
Author: [EMAIL], Click to see SCM information
use
Psr\Log\LoggerInterface;
Line: 16
Author: [EMAIL], Click to see SCM information
use
Sentry\Laravel\Facade
as
Sentry;
Line: 17
Author: [EMAIL], Click to see SCM information
use
Throwable;
Line: 18
Author: [EMAIL], Click to see SCM information
Line: 19
Author: [EMAIL], Click to see SCM information
class
SendReportNotGeneratedMailJob
implements
ShouldBeUnique, ShouldQueue
Line: 20
Author: [EMAIL], Click to see SCM information
{
Line: 21
Author: [EMAIL], Click to see SCM information
use
Dispatchable;
Line: 22
Author: [EMAIL], Click to see SCM information
use
InteractsWithQueue;
Line: 23
Author: [EMAIL], Click to see SCM information
use
Queueable;
Line: 24
Author: [EMAIL], Click to see SCM information
Line: 25
Author: [EMAIL], Click to see SCM information
private
const
string
LOG_PREFIX
=
'[Send Report Not Generated Mail]'
;
Line: 26
Author: [EMAIL], Click to see SCM information
Line: 27
Author: [EMAIL], Click to see SCM information
public
int
$tries
=
3
;
Line: 28
Author: [EMAIL], Click to see SCM information
Line: 29
Author: [EMAIL], Click to see SCM information
/**
Line: 30
Author: [EMAIL], Click to see SCM information
* @var array<int, int>
Line: 31
Author: [EMAIL], Click to see SCM information
*/
Line: 32
Author: [EMAIL], Click to see SCM information
public
array
$backoff
= [
60
,
300
,
600
];
Line: 33
Author: [EMAIL], Click to see SCM information
Line: 34
Author: [EMAIL], Click to see SCM information
public
int
$timeout
=
60
;
Line: 35
Author: [EMAIL], Click to see SCM information
Line: 36
Author: [EMAIL], Click to see SCM information
public
function
__construct
(
Line: 37
Author: [EMAIL], Click to see SCM information
private
readonly
string
$reportUuid
,
Line: 38
Author: [EMAIL], Click to see SCM information
private
readonly
string
$recipientEmail
,
Line: 39
Author: [EMAIL], Click to see SCM information
private
readonly
?string
$recipientName
,
Line: 40
Author: [EMAIL], Click to see SCM information
private
readonly
string
$reportName
,
Line: 41
Author: [EMAIL], Click to see SCM information
private
readonly
string
$periodName
,
Line: 42
Author: [EMAIL], Click to see SCM information
private
readonly
string
$reportsPageUrl
,
Line: 43
Author: [EMAIL], Click to see SCM information
) {
Line: 44
Author: [EMAIL], Click to see SCM information
$this
->onQueue(Constants::QUEUE_ANALYTICS_LOW);
Line: 45
Author: [EMAIL], Click to see SCM information
}
Line: 46
Author: [EMAIL], Click to see SCM information
Line: 47
Author: [EMAIL], Click to see SCM information
public
function
uniqueId
(): string
Line: 48
Author: [EMAIL], Click to see SCM information
{
Line: 49
Author: [EMAIL], Click to see SCM information
return
$this
->reportUuid .
'_not_generated_'
.
$this
->recipientEmail;
Line: 50
Author: [EMAIL], Click to see SCM information
}
Line: 51
Author: [EMAIL], Click to see SCM information
Line: 52
Author: [EMAIL], Click to see SCM information
public
function
handle
(LoggerInterface
$logger
): void
Line: 53
Author: [EMAIL], Click to see SCM information
{
Line: 54
Author: [EMAIL], Click to see SCM information
$mailSubject
=
"
Your '
{
$this
->reportName}
' report wasn't generated
"
;
Line: 55
Author: [EMAIL], Click to see SCM information
Line: 56
Author: [EMAIL], Click to see SCM information
try
{
Line: 57
Author: [EMAIL], Click to see SCM information
$mailable
=
new
ReportNotGenerated(
Line: 58
Author: [EMAIL], Click to see SCM information
reportName:
$this
->reportName,
Line: 59
Author: [EMAIL], Click to see SCM information
periodName:
$this
->periodName,
Line: 60
Author: [EMAIL], Click to see SCM information
reportsPageUrl:
$this
->reportsPageUrl,
Line: 61
Author: [EMAIL], Click to see SCM information
mailSubject:
$mailSubject
,
Line: 62
Author: [EMAIL], Click to see SCM information
);
Line: 63
Author: [EMAIL], Click to see SCM information
Line: 64
Author: [EMAIL], Click to see SCM information
Mail::mailer(
'postmark'
)
Line: 65
Author: [EMAIL], Click to see SCM information
->to(
$this
->recipientEmail)
Line: 66
Author: [EMAIL], Click to see SCM information
->send(
$mailable
);
Line: 67
Author: [EMAIL], Click to see SCM information
Line: 68
Author: [EMAIL], Click to see SCM information
$logger
->info(self::
LOG_PREFIX
.
' Email sent'
, [
Line: 69
Author: [EMAIL], Click to see SCM information
'uuid'
=>
$this
->reportUuid,
Line: 70
Author: [EMAIL], Click to see SCM information
'email'
=>
$this
->recipientEmail,
Line: 71
Author: [EMAIL], Click to see SCM information
'recipientName'
=>
$this
->recipientName,
Line: 72
Author: [EMAIL], Click to see SCM information
]);
Line: 73
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
}
catch
(Throwable
$e
) {
Line: 74
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
$logger
->error(self::
LOG_PREFIX
.
' Error sending email'
, [
Line: 75
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
'uuid'
=>
$this
->reportUuid,
Line: 76
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
'email'
=>
$this
->recipientEmail,
Line: 77
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
'error'
=>
$e
->getMessage(),
Line: 78
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
'trace'
=>
$e
->getTraceAsString(),
Line: 79
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
]);
Line: 80
Author: [EMAIL], Click to see SCM information
Duplicated block. Click for details.
Line: 81...
|
76322
|
|
76323
|
1909
|
31
|
2026-04-24T07:41:45.004219+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-24/1777 /Users/lukas/.screenpipe/data/data/2026-04-24/1777016505004_m1.jpg...
|
Firefox
|
Coverage on New Code - app in Jiminny SonarQube Cl Coverage on New Code - app in Jiminny SonarQube Cloud — Work...
|
1
|
sonarcloud.io/component_measures?metric=new_covera sonarcloud.io/component_measures?metric=new_coverage&selected=jiminny_app%3Aapp%2FJobs%2FAutomatedReports%2FSendReportNotGeneratedMailJob.php&view=list&pullRequest=12011&id=jiminny_app...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20489 | Optimize Nudges - Phase 2 by yalokin-jiminny · Pull Request #11997 · jiminny/app
JY-20489 | Optimize Nudges - Phase 2 by yalokin-jiminny · Pull Request #11997 · jiminny/app
New Tab
New Tab
AI reports promotion pages by nikolay-yankov · Pull Request #11998 · jiminny/app
AI reports promotion pages by nikolay-yankov · Pull Request #11998 · jiminny/app
JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app
JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app
Jiminny
Jiminny
Userpilot | Nudge-created
Userpilot | Nudge-created
Coverage on New Code - app in Jiminny SonarQube Cloud
Coverage on New Code - app in Jiminny SonarQube Cloud
Close tab
Pipelines - jiminny/app
Pipelines - jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to measure filters
Skip to measure filters
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture New
Architecture
New
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture New
Intended architecture
New
Project
Pull Requests 154
Pull Requests
154
Branches 16
Branches
16
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Measures
Measures
Measures
12011 – JY-20157 add not enough activities notification
12011 – JY-20157 add not enough activities notification
Project Overview
Security Domain help tooltip
Security
Reliability Domain help tooltip
Reliability
Maintainability Domain help tooltip
Maintainability
Security Review Domain help tooltip
Security Review
Coverage
Coverage
Coverage Has value: 6.3%
Coverage
6.3%
Lines to Cover Has value: 32
Lines to Cover
32
Uncovered Lines Has value: 30
Uncovered Lines
30
Line Coverage Has value: 6.3%
Line Coverage
6.3%
Conditions to Cover Has value: 0
Conditions to Cover
0
Uncovered Conditions Has value: 0
Uncovered Conditions
0
Duplications
Duplications
Size
Size
Issues
Issues
app
app
app
app
Jobs
Jobs
AutomatedReports
AutomatedReports
SendReportNotGeneratedMailJob.php
SendReportNotGeneratedMailJob.php
Copy to clipboard
Coverage on New Code
6.3%
Line: 1
Author: [EMAIL], Click to see SCM information
<?php
Line: 2
Author: [EMAIL], Click to see SCM information
Line: 3
Author: [EMAIL], Click to see SCM information
declare
(strict_types=
1
);
Line: 4
Author: [EMAIL], Click to see SCM information
Line: 5
Author: [EMAIL], Click to see SCM information
namespace
Jiminny\Jobs\AutomatedReports;
Line: 6
Author: [EMAIL], Click to see SCM information
Line: 7
Author: [EMAIL], Click to see SCM information
use
Illuminate\Bus\Queueable;
Line: 8
Author: [EMAIL], Click to see SCM information
use
Illuminate\Contracts\Queue\ShouldBeUnique;
Line: 9
Author: [EMAIL], Click to see SCM information
use
Illuminate\Contracts\Queue\ShouldQueue;
Line: 10
Author: [EMAIL], Click to see SCM information
use
Illuminate\Foundation\Bus\Dispatchable;
Line: 11
Author: [EMAIL], Click to see SCM information
use
Illuminate\Queue\InteractsWithQueue;
Line: 12
Author: [EMAIL], Click to see SCM information
use
Illuminate\Support\Facades\Mail;
Line: 13
Author: [EMAIL], Click to see SCM information
use
Jiminny\Component\Queue\Constants;
Line: 14
Author: [EMAIL], Click to see SCM information
use
Jiminny\Mail\Reports\ReportNotGenerated;
Line: 15
Author: [EMAIL], Click to see SCM information
use
Psr\Log\LoggerInterface;
Line: 16
Author: [EMAIL], Click to see SCM information
use
Sentry\Laravel\Facade
as
Sentry;
Line: 17
Author: [EMAIL], Click to see SCM information
use
Throwable;
Line: 18
Author: [EMAIL], Click to see SCM information
Line: 19
Author: [EMAIL], Click to see SCM information
class
SendReportNotGeneratedMailJob
implements
ShouldBeUnique, ShouldQueue
Line: 20
Author: [EMAIL], Click to see SCM information
{
Line: 21
Author: [EMAIL], Click to see SCM information
use
Dispatchable;
Line: 22
Author: [EMAIL], Click to see SCM information
use
InteractsWithQueue;
Line: 23
Author: [EMAIL], Click to see SCM information
use
Queueable;
Line: 24
Author: [EMAIL], Click to see SCM information
Line: 25
Author: [EMAIL], Click to see SCM information
private
const
string
LOG_PREFIX
=
'[Send Report Not Generated Mail]'
;
Line: 26
Author: [EMAIL], Click to see SCM information
Line: 27
Author: [EMAIL], Click to see SCM information
public
int
$tries
=
3
;
Line: 28
Author: [EMAIL], Click to see SCM information
Line: 29
Author: [EMAIL], Click to see SCM information
/**
Line: 30
Author: [EMAIL], Click to see SCM information
* @var array<int, int>
Line: 31
Author: [EMAIL], Click to see SCM information
*/
Line: 32
Author: [EMAIL], Click to see SCM information
public
array
$backoff
= [
60
,
300
,
600
];
Line: 33
Author: [EMAIL], Click to see SCM information
Line: 34
Author: [EMAIL], Click to see SCM information
public
int
$timeout
=
60
;
Line: 35
Author: [EMAIL], Click to see SCM information
Line: 36
Author: [EMAIL], Click to see SCM information
public
function
__construct
(
Line: 37
Author: [EMAIL], Click to see SCM information
private
readonly
string
$reportUuid
,
Line: 38
Author: [EMAIL], Click to see SCM information
private
readonly
string
$recipientEmail
,
Line: 39
Author: [EMAIL], Click to see SCM information
private
readonly
?string
$recipientName
,
Line: 40
Author: [EMAIL], Click to see SCM information
private
readonly
string
$reportName
,
Line: 41
Author: [EMAIL], Click to see SCM information
private
readonly
string
$periodName
,
Line: 42
Author: [EMAIL], Click to see SCM information
private
readonly
string
$reportsPageUrl
,
Line: 43
Author: [EMAIL], Click to see SCM information
) {
Line: 44
Author: [EMAIL], Click to see SCM information
$this
->onQueue(Constants::QUEUE_ANALYTICS_LOW);
Line: 45
Author: [EMAIL], Click to see SCM information
}
Line: 46
Author: [EMAIL], Click to see SCM information
Line: 47
Author: [EMAIL], Click to see SCM information
public
function
uniqueId
(): string
Line: 48
Author: [EMAIL], Click to see SCM information
{
Line: 49
Author: [EMAIL], Click to see SCM information
return
$this
->reportUuid .
'_not_generated_'
.
$this
->recipientEmail;
Line: 50
Author: [EMAIL], Click to see SCM information
}
Line: 51
Author: [EMAIL], Click to see SCM information
Line: 52
Author: [EMAIL], Click to see SCM information
public
function
handle
(LoggerInterface
$logger
): void
Line: 53
Author: [EMAIL], Click to see SCM information
{
Line: 54
Author: [EMAIL], Click to see SCM information
$mailSubject
=
"
Your '
{
$this
->reportName}
' report wasn't generated
"
;
Line: 55
Author: [EMAIL], Click to see SCM information
Line: 56
Author: [EMAIL], Click to see SCM information
try
{
Line: 57
Author: [EMAIL], Click to see SCM information...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20489 | Optimize Nudges - Phase 2 by yalokin-jiminny · Pull Request #11997 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20489 | Optimize Nudges - Phase 2 by yalokin-jiminny · Pull Request #11997 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"AI reports promotion pages by nikolay-yankov · Pull Request #11998 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AI reports promotion pages by nikolay-yankov · Pull Request #11998 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Userpilot | Nudge-created","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Userpilot | Nudge-created","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Coverage on New Code - app in Jiminny SonarQube Cloud","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Coverage on New Code - app in Jiminny SonarQube Cloud","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.016666668,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to main content","depth":7,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Skip to measure filters","depth":7,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to measure filters","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Undock sidebar","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Continuous Code Quality","depth":8,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Favorite Projects","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Favorite Projects","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Assigned Issues","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Assigned Issues","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Product news","depth":8,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New...","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Account","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Overview","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Overview","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Analysis","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Summary","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summary","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Architecture New","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Architecture","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"New","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security hotspots","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security hotspots","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Reporting","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Measures","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Measures","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Activity","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Policies","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Intended architecture New","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Intended architecture","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"New","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Project","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull Requests 154","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull Requests","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"154","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Branches 16","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Branches","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"16","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Project Information","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Project Information","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jiminny","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Measures","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Measures","depth":8,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Measures","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12011 – JY-20157 add not enough activities notification","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"12011 – JY-20157 add not enough activities notification","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Project Overview","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Security Domain help tooltip","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Security","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reliability Domain help tooltip","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reliability","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Maintainability Domain help tooltip","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Maintainability","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Security Review Domain help tooltip","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Security Review","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Coverage","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Coverage","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Coverage Has value: 6.3%","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Coverage","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6.3%","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Lines to Cover Has value: 32","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lines to Cover","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"32","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Uncovered Lines Has value: 30","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Uncovered Lines","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line Coverage Has value: 6.3%","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Line Coverage","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6.3%","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Conditions to Cover Has value: 0","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Conditions to Cover","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Uncovered Conditions Has value: 0","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Uncovered Conditions","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Duplications","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Duplications","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Size","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Size","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Issues","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Issues","depth":11,"bounds":{"left":0.27743056,"top":0.0,"width":0.030555556,"height":0.019444445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Jobs","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jobs","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"AutomatedReports","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AutomatedReports","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SendReportNotGeneratedMailJob.php","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SendReportNotGeneratedMailJob.php","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy to clipboard","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Coverage on New Code","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6.3%","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 1","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"<?php","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 2","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 3","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"declare","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(strict_types=","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 4","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 5","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"namespace","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Jobs\\AutomatedReports;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 6","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 7","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Bus\\Queueable;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 8","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Contracts\\Queue\\ShouldBeUnique;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 9","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Contracts\\Queue\\ShouldQueue;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 10","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Foundation\\Bus\\Dispatchable;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 11","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Queue\\InteractsWithQueue;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 12","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Illuminate\\Support\\Facades\\Mail;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 13","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Component\\Queue\\Constants;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 14","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny\\Mail\\Reports\\ReportNotGenerated;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 15","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Psr\\Log\\LoggerInterface;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 16","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sentry\\Laravel\\Facade","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"as","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sentry;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 17","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Throwable;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 18","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 19","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"class","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SendReportNotGeneratedMailJob","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"implements","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ShouldBeUnique, ShouldQueue","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 20","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"{","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 21","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dispatchable;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 22","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"InteractsWithQueue;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 23","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"use","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Queueable;","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 24","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 25","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"const","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"LOG_PREFIX","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'[Send Report Not Generated Mail]'","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 26","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 27","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"int","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$tries","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 28","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 29","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"/**","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 30","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"* @var array<int, int>","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 31","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"*/","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 32","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"array","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$backoff","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"= [","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"60","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"300","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"600","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"];","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 33","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 34","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"int","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$timeout","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"60","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 35","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 36","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"__construct","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 37","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"readonly","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$reportUuid","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 38","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"readonly","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$recipientEmail","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 39","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"bounds":{"left":0.76354164,"top":0.0,"width":0.034027778,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"readonly","depth":14,"bounds":{"left":0.80243057,"top":0.0,"width":0.03888889,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"?string","depth":14,"bounds":{"left":0.84131944,"top":0.0,"width":0.04375,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$recipientName","depth":14,"bounds":{"left":0.88506943,"top":0.0,"width":0.068055555,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.953125,"top":0.0,"width":0.0048611113,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 40","depth":12,"bounds":{"left":0.62951386,"top":0.0,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.0,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"bounds":{"left":0.76354164,"top":0.0,"width":0.034027778,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"readonly","depth":14,"bounds":{"left":0.80243057,"top":0.0,"width":0.03888889,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":14,"bounds":{"left":0.84131944,"top":0.0,"width":0.03888889,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$reportName","depth":14,"bounds":{"left":0.8802083,"top":0.0,"width":0.05347222,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.93368053,"top":0.0,"width":0.0048611113,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 41","depth":12,"bounds":{"left":0.62951386,"top":0.0,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.0,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"bounds":{"left":0.76354164,"top":0.0,"width":0.034027778,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"readonly","depth":14,"bounds":{"left":0.80243057,"top":0.0,"width":0.03888889,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":14,"bounds":{"left":0.84131944,"top":0.0,"width":0.03888889,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$periodName","depth":14,"bounds":{"left":0.8802083,"top":0.0,"width":0.05347222,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.93368053,"top":0.0,"width":0.0048611113,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 42","depth":12,"bounds":{"left":0.62951386,"top":0.0,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.0,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"private","depth":14,"bounds":{"left":0.76354164,"top":0.0,"width":0.034027778,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"readonly","depth":14,"bounds":{"left":0.80243057,"top":0.0,"width":0.03888889,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"string","depth":14,"bounds":{"left":0.84131944,"top":0.0,"width":0.03888889,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$reportsPageUrl","depth":14,"bounds":{"left":0.8802083,"top":0.0,"width":0.072916664,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":14,"bounds":{"left":0.953125,"top":0.0,"width":0.0048611113,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 43","depth":12,"bounds":{"left":0.62951386,"top":0.0,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.0,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":") {","depth":14,"bounds":{"left":0.72465277,"top":0.0,"width":0.034027778,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 44","depth":12,"bounds":{"left":0.62951386,"top":0.01,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.01,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"$this","depth":14,"bounds":{"left":0.76354164,"top":0.013333334,"width":0.024305556,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->onQueue(Constants::QUEUE_ANALYTICS_LOW);","depth":14,"bounds":{"left":0.7878472,"top":0.013333334,"width":0.20416667,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 45","depth":12,"bounds":{"left":0.62951386,"top":0.032222223,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.032222223,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"}","depth":14,"bounds":{"left":0.72465277,"top":0.035555556,"width":0.024305556,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 46","depth":12,"bounds":{"left":0.62951386,"top":0.054444443,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.054444443,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 47","depth":12,"bounds":{"left":0.62951386,"top":0.07666667,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.07666667,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":14,"bounds":{"left":0.74409723,"top":0.08,"width":0.029166667,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":14,"bounds":{"left":0.778125,"top":0.08,"width":0.03888889,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"uniqueId","depth":14,"bounds":{"left":0.821875,"top":0.08,"width":0.03888889,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(): string","depth":14,"bounds":{"left":0.8607639,"top":0.08,"width":0.048611112,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 48","depth":12,"bounds":{"left":0.62951386,"top":0.09888889,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.09888889,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"{","depth":14,"bounds":{"left":0.72465277,"top":0.10222222,"width":0.024305556,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 49","depth":12,"bounds":{"left":0.62951386,"top":0.12111111,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.12111111,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"return","depth":14,"bounds":{"left":0.76354164,"top":0.12444445,"width":0.029166667,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"bounds":{"left":0.79756945,"top":0.12444445,"width":0.024305556,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->reportUuid .","depth":14,"bounds":{"left":0.821875,"top":0.12444445,"width":0.072916664,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'_not_generated_'","depth":14,"bounds":{"left":0.89479166,"top":0.12444445,"width":0.08263889,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":14,"bounds":{"left":0.9774306,"top":0.12444445,"width":0.014583333,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"bounds":{"left":0.9920139,"top":0.12444445,"width":0.007986128,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->recipientEmail;","depth":14,"bounds":{"left":1.0,"top":0.12444445,"width":-0.016319394,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 50","depth":12,"bounds":{"left":0.62951386,"top":0.14333333,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.14333333,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"}","depth":14,"bounds":{"left":0.72465277,"top":0.14666666,"width":0.024305556,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 51","depth":12,"bounds":{"left":0.62951386,"top":0.16555555,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.16555555,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 52","depth":12,"bounds":{"left":0.62951386,"top":0.18777777,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.18777777,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"public","depth":14,"bounds":{"left":0.74409723,"top":0.19111112,"width":0.029166667,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":14,"bounds":{"left":0.778125,"top":0.19111112,"width":0.03888889,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"handle","depth":14,"bounds":{"left":0.821875,"top":0.19111112,"width":0.029166667,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(LoggerInterface","depth":14,"bounds":{"left":0.8510417,"top":0.19111112,"width":0.08263889,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$logger","depth":14,"bounds":{"left":0.93368053,"top":0.19111112,"width":0.034027778,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"): void","depth":14,"bounds":{"left":0.96770835,"top":0.19111112,"width":0.03229165,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 53","depth":12,"bounds":{"left":0.62951386,"top":0.21,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.21,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"{","depth":14,"bounds":{"left":0.72465277,"top":0.21333334,"width":0.024305556,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 54","depth":12,"bounds":{"left":0.62951386,"top":0.23222223,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.23222223,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"$mailSubject","depth":14,"bounds":{"left":0.76354164,"top":0.23555556,"width":0.058333334,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":14,"bounds":{"left":0.821875,"top":0.23555556,"width":0.014583333,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"","depth":14,"bounds":{"left":0.8364583,"top":0.23555556,"width":0.0048611113,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your '","depth":14,"bounds":{"left":0.84131944,"top":0.23555556,"width":0.029166667,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"{","depth":14,"bounds":{"left":0.87048614,"top":0.23555556,"width":0.0048611113,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$this","depth":14,"bounds":{"left":0.8753472,"top":0.23555556,"width":0.024305556,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->reportName}","depth":14,"bounds":{"left":0.8996528,"top":0.23555556,"width":0.063194446,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"' report wasn't generated","depth":14,"bounds":{"left":0.96284723,"top":0.23555556,"width":0.037152767,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"\"","depth":14,"bounds":{"left":1.0,"top":0.23555556,"width":-0.084375024,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":14,"bounds":{"left":1.0,"top":0.23555556,"width":-0.08923614,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 55","depth":12,"bounds":{"left":0.62951386,"top":0.25444445,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.25444445,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Line: 56","depth":12,"bounds":{"left":0.62951386,"top":0.27666667,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.27666667,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"try","depth":14,"bounds":{"left":0.76354164,"top":0.28,"width":0.014583333,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"{","depth":14,"bounds":{"left":0.778125,"top":0.28,"width":0.009722223,"height":0.016111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Line: 57","depth":12,"bounds":{"left":0.62951386,"top":0.2988889,"width":0.015277778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Author: kovaliklukas@gmail.com, Click to see SCM information","depth":13,"bounds":{"left":0.6545139,"top":0.2988889,"width":0.04027778,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-4073886754591018388
|
9040406994006222650
|
app_switch
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20489 | Optimize Nudges - Phase 2 by yalokin-jiminny · Pull Request #11997 · jiminny/app
JY-20489 | Optimize Nudges - Phase 2 by yalokin-jiminny · Pull Request #11997 · jiminny/app
New Tab
New Tab
AI reports promotion pages by nikolay-yankov · Pull Request #11998 · jiminny/app
AI reports promotion pages by nikolay-yankov · Pull Request #11998 · jiminny/app
JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app
JY-9712 | Nuges to expire after one year by nikolaybiaivanov · Pull Request #11981 · jiminny/app
Jiminny
Jiminny
Userpilot | Nudge-created
Userpilot | Nudge-created
Coverage on New Code - app in Jiminny SonarQube Cloud
Coverage on New Code - app in Jiminny SonarQube Cloud
Close tab
Pipelines - jiminny/app
Pipelines - jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to main content
Skip to main content
Skip to measure filters
Skip to measure filters
Undock sidebar
Continuous Code Quality
Favorite Projects
Favorite Projects
Assigned Issues
Assigned Issues
Explore
Explore
Search
Product news
1
Help
New...
Account
app
Project
Overview
Overview
Analysis
Summary
Summary
Issues
Issues
Architecture New
Architecture
New
Security hotspots
Security hotspots
Reporting
Measures
Measures
Activity
Activity
Policies
Intended architecture New
Intended architecture
New
Project
Pull Requests 154
Pull Requests
154
Branches 16
Branches
16
Code
Code
Project Information
Project Information
Jiminny
Jiminny
app
app
Measures
Measures
Measures
12011 – JY-20157 add not enough activities notification
12011 – JY-20157 add not enough activities notification
Project Overview
Security Domain help tooltip
Security
Reliability Domain help tooltip
Reliability
Maintainability Domain help tooltip
Maintainability
Security Review Domain help tooltip
Security Review
Coverage
Coverage
Coverage Has value: 6.3%
Coverage
6.3%
Lines to Cover Has value: 32
Lines to Cover
32
Uncovered Lines Has value: 30
Uncovered Lines
30
Line Coverage Has value: 6.3%
Line Coverage
6.3%
Conditions to Cover Has value: 0
Conditions to Cover
0
Uncovered Conditions Has value: 0
Uncovered Conditions
0
Duplications
Duplications
Size
Size
Issues
Issues
app
app
app
app
Jobs
Jobs
AutomatedReports
AutomatedReports
SendReportNotGeneratedMailJob.php
SendReportNotGeneratedMailJob.php
Copy to clipboard
Coverage on New Code
6.3%
Line: 1
Author: [EMAIL], Click to see SCM information
<?php
Line: 2
Author: [EMAIL], Click to see SCM information
Line: 3
Author: [EMAIL], Click to see SCM information
declare
(strict_types=
1
);
Line: 4
Author: [EMAIL], Click to see SCM information
Line: 5
Author: [EMAIL], Click to see SCM information
namespace
Jiminny\Jobs\AutomatedReports;
Line: 6
Author: [EMAIL], Click to see SCM information
Line: 7
Author: [EMAIL], Click to see SCM information
use
Illuminate\Bus\Queueable;
Line: 8
Author: [EMAIL], Click to see SCM information
use
Illuminate\Contracts\Queue\ShouldBeUnique;
Line: 9
Author: [EMAIL], Click to see SCM information
use
Illuminate\Contracts\Queue\ShouldQueue;
Line: 10
Author: [EMAIL], Click to see SCM information
use
Illuminate\Foundation\Bus\Dispatchable;
Line: 11
Author: [EMAIL], Click to see SCM information
use
Illuminate\Queue\InteractsWithQueue;
Line: 12
Author: [EMAIL], Click to see SCM information
use
Illuminate\Support\Facades\Mail;
Line: 13
Author: [EMAIL], Click to see SCM information
use
Jiminny\Component\Queue\Constants;
Line: 14
Author: [EMAIL], Click to see SCM information
use
Jiminny\Mail\Reports\ReportNotGenerated;
Line: 15
Author: [EMAIL], Click to see SCM information
use
Psr\Log\LoggerInterface;
Line: 16
Author: [EMAIL], Click to see SCM information
use
Sentry\Laravel\Facade
as
Sentry;
Line: 17
Author: [EMAIL], Click to see SCM information
use
Throwable;
Line: 18
Author: [EMAIL], Click to see SCM information
Line: 19
Author: [EMAIL], Click to see SCM information
class
SendReportNotGeneratedMailJob
implements
ShouldBeUnique, ShouldQueue
Line: 20
Author: [EMAIL], Click to see SCM information
{
Line: 21
Author: [EMAIL], Click to see SCM information
use
Dispatchable;
Line: 22
Author: [EMAIL], Click to see SCM information
use
InteractsWithQueue;
Line: 23
Author: [EMAIL], Click to see SCM information
use
Queueable;
Line: 24
Author: [EMAIL], Click to see SCM information
Line: 25
Author: [EMAIL], Click to see SCM information
private
const
string
LOG_PREFIX
=
'[Send Report Not Generated Mail]'
;
Line: 26
Author: [EMAIL], Click to see SCM information
Line: 27
Author: [EMAIL], Click to see SCM information
public
int
$tries
=
3
;
Line: 28
Author: [EMAIL], Click to see SCM information
Line: 29
Author: [EMAIL], Click to see SCM information
/**
Line: 30
Author: [EMAIL], Click to see SCM information
* @var array<int, int>
Line: 31
Author: [EMAIL], Click to see SCM information
*/
Line: 32
Author: [EMAIL], Click to see SCM information
public
array
$backoff
= [
60
,
300
,
600
];
Line: 33
Author: [EMAIL], Click to see SCM information
Line: 34
Author: [EMAIL], Click to see SCM information
public
int
$timeout
=
60
;
Line: 35
Author: [EMAIL], Click to see SCM information
Line: 36
Author: [EMAIL], Click to see SCM information
public
function
__construct
(
Line: 37
Author: [EMAIL], Click to see SCM information
private
readonly
string
$reportUuid
,
Line: 38
Author: [EMAIL], Click to see SCM information
private
readonly
string
$recipientEmail
,
Line: 39
Author: [EMAIL], Click to see SCM information
private
readonly
?string
$recipientName
,
Line: 40
Author: [EMAIL], Click to see SCM information
private
readonly
string
$reportName
,
Line: 41
Author: [EMAIL], Click to see SCM information
private
readonly
string
$periodName
,
Line: 42
Author: [EMAIL], Click to see SCM information
private
readonly
string
$reportsPageUrl
,
Line: 43
Author: [EMAIL], Click to see SCM information
) {
Line: 44
Author: [EMAIL], Click to see SCM information
$this
->onQueue(Constants::QUEUE_ANALYTICS_LOW);
Line: 45
Author: [EMAIL], Click to see SCM information
}
Line: 46
Author: [EMAIL], Click to see SCM information
Line: 47
Author: [EMAIL], Click to see SCM information
public
function
uniqueId
(): string
Line: 48
Author: [EMAIL], Click to see SCM information
{
Line: 49
Author: [EMAIL], Click to see SCM information
return
$this
->reportUuid .
'_not_generated_'
.
$this
->recipientEmail;
Line: 50
Author: [EMAIL], Click to see SCM information
}
Line: 51
Author: [EMAIL], Click to see SCM information
Line: 52
Author: [EMAIL], Click to see SCM information
public
function
handle
(LoggerInterface
$logger
): void
Line: 53
Author: [EMAIL], Click to see SCM information
{
Line: 54
Author: [EMAIL], Click to see SCM information
$mailSubject
=
"
Your '
{
$this
->reportName}
' report wasn't generated
"
;
Line: 55
Author: [EMAIL], Click to see SCM information
Line: 56
Author: [EMAIL], Click to see SCM information
try
{
Line: 57
Author: [EMAIL], Click to see SCM information...
|
NULL
|
|
79281
|
2049
|
6
|
2026-04-24T15:56:04.172624+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-24/1777 /Users/lukas/.screenpipe/data/data/2026-04-24/1777046164172_m1.jpg...
|
Music
|
Music
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Search
Apple Music
Home
Radio
Library
Recently Add Search
Apple Music
Home
Radio
Library
Recently Added
Artists
Albums
Songs...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Search","depth":7,"bounds":{"left":0.007638889,"top":0.101111114,"width":0.017361112,"height":0.024444444},"role_description":"button","is_enabled":true,"is_focused":false},{"role":"AXStaticText","text":"Apple Music","depth":6,"bounds":{"left":0.009027778,"top":0.14666666,"width":0.14166667,"height":0.015555556},"role_description":"text"},{"role":"AXStaticText","text":"Home","depth":6,"bounds":{"left":0.031944446,"top":0.17222223,"width":0.10902778,"height":0.017777778},"role_description":"text"},{"role":"AXStaticText","text":"Radio","depth":6,"bounds":{"left":0.031944446,"top":0.20333333,"width":0.10902778,"height":0.017777778},"role_description":"text"},{"role":"AXStaticText","text":"Library","depth":6,"bounds":{"left":0.009027778,"top":0.24444444,"width":0.13263889,"height":0.015555556},"role_description":"text"},{"role":"AXStaticText","text":"Recently Added","depth":6,"bounds":{"left":0.031944446,"top":0.27,"width":0.10902778,"height":0.017777778},"role_description":"text"},{"role":"AXStaticText","text":"Artists","depth":6,"bounds":{"left":0.031944446,"top":0.3011111,"width":0.10902778,"height":0.017777778},"role_description":"text"},{"role":"AXStaticText","text":"Albums","depth":6,"bounds":{"left":0.031944446,"top":0.33222222,"width":0.10902778,"height":0.017777778},"role_description":"text"},{"role":"AXStaticText","text":"Songs","depth":6,"bounds":{"left":0.031944446,"top":0.36333334,"width":0.10902778,"height":0.017777778},"role_description":"text"}]...
|
7513314412868490249
|
9036716104603295205
|
visual_change
|
hybrid
|
NULL
|
Search
Apple Music
Home
Radio
Library
Recently Add Search
Apple Music
Home
Radio
Library
Recently Added
Artists
Albums
Songs
MusicFile•EditSongViewControlsAccountWindowHelp100% <47Fri 24 Apr 18:56:05QSearchApple Music• Home((•*) RadioLibrary• Recently Addedk ArtistsÔ AlbumsJ SongsStore* iTunes StorePlaylists883 All PlaylistsEf Internet SongsRecently Added2025BluetoothDevicesLukas's Magic Mousesoundcore AeroClipLakyLak bose qc35 llM720 TriathlonMagic Keyboard80% ©Magic Keyboard with Numeric KeypadSoundcore Life Dot 2 NCBluetooth Settings...start machineChatLLM Teams TTSCall to Robinson Crusoe Nov 2220242024output 2ffc1839a-520f-4619-8c06-3fc4966223646e5cbce9-0b1e-4556-ae01-10b2e491ee17105f8bc8-d065-4fdd-abf6-27d8afad9513ed9e817e-f202-4d5f-b8b3-92a19fde8535...
|
NULL
|
|
70225
|
1639
|
21
|
2026-04-22T09:58:09.536384+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-22/1776 /Users/lukas/.screenpipe/data/data/2026-04-22/1776851889536_m2.jpg...
|
Firefox
|
CloudWatch | us-east-2 — Work
|
1
|
us-east-2.console.aws.amazon.com/cloudwatch/home?r us-east-2.console.aws.amazon.com/cloudwatch/home?region=us-east-2#logsV2:logs-insights$3FqueryDetail$3D~(end~0~start~-3600~timeType~'RELATIVE~tz~'UTC~unit~'seconds~editorString~'fields*20*40timestamp*2c*20*40message*2c*20*40logStream*2c*20*40log*0a*7c*20filter*20*40message*20like*20*2f74049485*2f*20*0a*7c*20filter*20*40message*20not*20like*20*2fAnalytic*2f*20*7c*20filter*20*40message*20not*20like*20*2fTranscript*2f*0a*7c*20filter*20*40message*20not*20like*20*2fWebhook*2f*20*7c*20filter*20*40message*20not*20like*20*2fMeetingBot*2f*20*0a*7c*20limit*2010000~queryId~'0551e814-f51a-4339-8372-80d7ba4cef27~source~(~'worker~'worker-analytics~'worker-app~'worker-audio~'worker-calendar~'worker-conferences~'worker-crm-sync~'worker-default~'worker-delayed~'worker-dialers~'worker-dialers-fifo~'worker-download~'worker-emails~'worker-meeting-bot~'worker-nudges~'worker-processing-1~'worker-processing-2~'worker-processing-3~'worker-processing-4~'worker-processing-5~'worker-processing-delayed~'worker-softphone~'worker-video~'worker-video-app~'php~'php-app)~lang~'CWLI~logClass~'STANDARD~queryBy~'logGroupName)...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
[JY-20372] AI Reports > Empty page design and promotion - Jira
[JY-20372] AI Reports > Empty page design and promotion - Jira
Jiminny MCP Connector - Product - Confluence
Jiminny MCP Connector - Product - Confluence
CRM issues - Apr 22 - Chat
CRM issues - Apr 22 - Chat
[JY-20500] Batch initial sync for Salesforce - Jira
[JY-20500] Batch initial sync for Salesforce - Jira
Feed — jiminny — Sentry
Feed — jiminny — Sentry
Jiminny
Jiminny
Pipelines - /app
Pipelines - /app
Formalize
Formalize
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
Search results: calendar | Jiminny Help Center
Search results: calendar | Jiminny Help Center
Jiminny
Jiminny
Jiminny
Jiminny
Jiminny
Jiminny
Edit - Engineering - Confluence
Edit - Engineering - Confluence
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Workers | Datadog
Workers | Datadog
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom
Custom
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Completed. Query executed for
26 log groups.
View log groups used in query
Logs (15)
Logs
(
15
)
Patterns (8)
Patterns
(
8
)
Visualization
Visualization
Logs (15)
Logs (15)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
Showing 15 of 15 records matched
11,743,819 records (2.7 GB) scanned in 6.1s @ 1,935,368 records/s (451.6 MB/s)
Hide histogram
Hide histogram
Filter table results
2026-04-21T16:18:23.207Z
[2026-04-21 16:18:23] production.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":74049485,"remote_search":true,"lead_id":null,"contact_id":null,"account_id":19003658,"opportunity_id":null,"stage_id":null} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:23.203Z
[2026-04-21 16:18:23] production.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":74049485,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:23.202Z
[2026-04-21 16:18:23] production.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":74049485} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:23.200Z
[2026-04-21 16:18:23] production.INFO: [CrmActivityService] CRM matching completed {"activity_id":74049485,"participants_processed":2,"exact_matches":0,"domain_matches":1,"best_match_found":true} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:22.732Z
[2026-04-21 16:18:22] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":74049485,"team_id":563,"email":"[EMAIL]"} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:22.718Z
[2026-04-21 16:18:22] production.INFO: [MatchActivityCrmData] Participants old state {"activity":74049485,"participants":[{"id":228313765,"user_id":28994,"contact_id":null,"lead_id":null},{"id":228313766,"user_id":null,"contact_id":null,"lead_id":null}]} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:22.717Z
[2026-04-21 16:18:22] production.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":74049485,"remote_search":true,"set_configuration":null,"old_state":{"lead_id":null,"contact_id":null,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:52.682Z
[2026-04-21 16:16:52] production.ERROR: [MatchActivityCrmData] Failed to match CRM data {"activity":74049485,"remote_search":true,"exception":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:52.331Z
[2026-04-21 16:16:52] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":74049485,"team_id":563,"email":"[EMAIL]"} {"correlation_id":"3db09bd8-5f91-43f3-a13a-7f16d41813e3","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:52.308Z
[2026-04-21 16:16:52] production.INFO: [MatchActivityCrmData] Participants old state {"activity":74049485,"participants":[{"id":228313765,"user_id":28994,"contact_id":null,"lead_id":null},{"id":228313766,"user_id":null,"contact_id":null,"lead_id":null}]} {"correlation_id":"3db09bd8-5f91-43f3-a13a-7f16d41813e3","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:52.306Z
[2026-04-21 16:16:52] production.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":74049485,"remote_search":true,"set_configuration":null,"old_state":{"lead_id":null,"contact_id":null,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"3db09bd8-5f91-43f3-a13a-7f16d41813e3","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:22.246Z
[2026-04-21 16:16:22] production.ERROR: [MatchActivityCrmData] Failed to match CRM data {"activity":74049485,"remote_search":true,"exception":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:21.911Z
[2026-04-21 16:16:21] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":74049485,"team_id":563,"email":"[EMAIL]"} {"correlation_id":"249bfb31-785c-4c1b-9937-5416b8975345","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:21.879Z
[2026-04-21 16:16:21] production.INFO: [MatchActivityCrmData] Participants old state {"activity":74049485,"participants":[{"id":228313765,"user_id":28994,"contact_id":null,"lead_id":null},{"id":228313766,"user_id":null,"contact_id":null,"lead_id":null}]} {"correlation_id":"249bfb31-785c-4c1b-9937-5416b8975345","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:21.875Z
[2026-04-21 16:16:21] production.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":74049485,"remote_search":true,"set_configuration":null,"old_state":{"lead_id":null,"contact_id":null,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"249bfb31-785c-4c1b-9937-5416b8975345","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:23.207Z
2026-04-21T16:18:23.203Z
2026-04-21T16:18:23.202Z
2026-04-21T16:18:23.200Z
2026-04-21T16:18:22.732Z
2026-04-21T16:18:22.718Z
2026-04-21T16:18:22.717Z
2026-04-21T16:16:52.682Z
2026-04-21T16:16:52.331Z
2026-04-21T16:16:52.308Z
2026-04-21T16:16:52.306Z
2026-04-21T16:16:22.246Z
2026-04-21T16:16:21.911Z
2026-04-21T16:16:21.879Z
2026-04-21T16:16:21.875Z
[2026-04-21 16:18:23] production.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":74049485,"remote_search":true,"lead_id":null,"contact_id":null,"account_id":19003658,"opportunity_id":null,"stage_id":null} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:18:23] production.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":74049485,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:18:23] production.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":74049485} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:18:23] production.INFO: [CrmActivityService] CRM matching completed {"activity_id":74049485,"participants_processed":2,"exact_matches":0,"domain_matches":1,"best_match_found":true} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:18:22] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":74049485,"team_id":563,"email":"[EMAIL]"} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:18:22] production.INFO: [MatchActivityCrmData] Participants old state {"activity":74049485,"participants":[{"id":228313765,"user_id":28994,"contact_id":null,"lead_id":null},{"id":228313766,"user_id":null,"contact_id":null,"lead_id":null}]} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:18:22] production.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":74049485,"remote_search":true,"set_configuration":null,"old_state":{"lead_id":null,"contact_id":null,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:16:52] production.ERROR: [MatchActivityCrmData] Failed to match CRM data {"activity":74049485,"remote_search":true,"exception":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
[2026-04-21 16:16:52] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":74049485,"team_id":563,"email":"[EMAIL]"} {"correlation_id":"3db09bd8-5f91-43f3-a13a-7f16d41813e3","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:16:52] production.INFO: [MatchActivityCrmData] Participants old state {"activity":74049485,"participants":[{"id":228313765,"user_id":28994,"contact_id":null,"lead_id":null},{"id":228313766,"user_id":null,"contact_id":null,"lead_id":null}]} {"correlation_id":"3db09bd8-5f91-43f3-a13a-7f16d41813e3","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:16:52] production.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":74049485,"remote_search":true,"set_configuration":null,"old_state":{"lead_id":null,"contact_id":null,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"3db09bd8-5f91-43f3-a13a-7f16d41813e3","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:16:22] production.ERROR: [MatchActivityCrmData] Failed to match CRM data {"activity":74049485,"remote_search":true,"exception":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
[2026-04-21 16:16:21] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":74049485,"team_id":563,"email":"[EMAIL]"} {"correlation_id":"249bfb31-785c-4c1b-9937-5416b8975345","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:16:21] production.INFO: [MatchActivityCrmData] Participants old state {"activity":74049485,"participants":[{"id":228313765,"user_id":28994,"contact_id":null,"lead_id":null},{"id":228313766,"user_id":null,"contact_id":null,"lead_id":null}]} {"correlation_id":"249bfb31-785c-4c1b-9937-5416b8975345","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:16:21] production.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":74049485,"remote_search":true,"set_configuration":null,"old_state":{"lead_id":null,"contact_id":null,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"249bfb31-785c-4c1b-9937-5416b8975345","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab
worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.28307846,"top":0.0518755,"width":0.07596409,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.28125,"top":0.09497207,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.2945479,"top":0.10614525,"width":0.10106383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"bounds":{"left":0.28125,"top":0.12769353,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"bounds":{"left":0.2945479,"top":0.13886672,"width":0.4644282,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20372] AI Reports > Empty page design and promotion - Jira","depth":4,"bounds":{"left":0.28125,"top":0.16041501,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20372] AI Reports > Empty page design and promotion - Jira","depth":5,"bounds":{"left":0.2945479,"top":0.17158818,"width":0.11319814,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny MCP Connector - Product - Confluence","depth":4,"bounds":{"left":0.28125,"top":0.19313647,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny MCP Connector - Product - Confluence","depth":5,"bounds":{"left":0.2945479,"top":0.20430966,"width":0.08294548,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CRM issues - Apr 22 - Chat","depth":4,"bounds":{"left":0.28125,"top":0.22585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CRM issues - Apr 22 - Chat","depth":5,"bounds":{"left":0.2945479,"top":0.23703113,"width":0.047706116,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20500] Batch initial sync for Salesforce - Jira","depth":4,"bounds":{"left":0.28125,"top":0.2585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20500] Batch initial sync for Salesforce - Jira","depth":5,"bounds":{"left":0.2945479,"top":0.2697526,"width":0.08610372,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.28125,"top":0.29130086,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.2945479,"top":0.30247405,"width":0.042719416,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.28125,"top":0.32402235,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.2945479,"top":0.33519554,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - /app","depth":4,"bounds":{"left":0.28125,"top":0.3567438,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - /app","depth":5,"bounds":{"left":0.2945479,"top":0.367917,"width":0.027094414,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Formalize","depth":4,"bounds":{"left":0.28125,"top":0.38946527,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Formalize","depth":5,"bounds":{"left":0.2945479,"top":0.40063846,"width":0.016788565,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"bounds":{"left":0.28125,"top":0.42218676,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"bounds":{"left":0.2945479,"top":0.43335995,"width":0.09524601,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Search results: calendar | Jiminny Help Center","depth":4,"bounds":{"left":0.28125,"top":0.45490822,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search results: calendar | Jiminny Help Center","depth":5,"bounds":{"left":0.2945479,"top":0.4660814,"width":0.080119684,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.28125,"top":0.48762968,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.2945479,"top":0.49880287,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.28125,"top":0.5203512,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.2945479,"top":0.53152436,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.28125,"top":0.55307263,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.2945479,"top":0.5642458,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Edit - Engineering - Confluence","depth":4,"bounds":{"left":0.28125,"top":0.5857941,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Edit - Engineering - Confluence","depth":5,"bounds":{"left":0.2945479,"top":0.5969673,"width":0.054853722,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":4,"bounds":{"left":0.28125,"top":0.61851555,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":5,"bounds":{"left":0.2945479,"top":0.62968874,"width":0.10688165,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"bounds":{"left":0.28125,"top":0.651237,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"bounds":{"left":0.2945479,"top":0.6624102,"width":0.4644282,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.28125,"top":0.6839585,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.2945479,"top":0.69513166,"width":0.041223403,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.34857047,"top":0.69114125,"width":0.007978723,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"bounds":{"left":0.28125,"top":0.71668,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"bounds":{"left":0.2945479,"top":0.7278532,"width":0.4644282,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Workers | Datadog","depth":4,"bounds":{"left":0.28125,"top":0.74940145,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Workers | Datadog","depth":5,"bounds":{"left":0.2945479,"top":0.76057464,"width":0.032081116,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.28125,"top":0.7821229,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.2945479,"top":0.7932961,"width":0.04537899,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.2840758,"top":0.8164405,"width":0.07413564,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.2840758,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.29504654,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.30618352,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.31732047,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.32845744,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"AWS Console Home","depth":13,"bounds":{"left":0.36087102,"top":0.055067837,"width":0.021609042,"height":0.03830806},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to Main Content","depth":13,"bounds":{"left":0.36053857,"top":0.054269753,"width":0.0013297872,"height":0.0015961692},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to Main Content","depth":14,"bounds":{"left":0.36120346,"top":0.055067837,"width":0.01662234,"height":0.051476456},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon Q","depth":14,"bounds":{"left":0.3828125,"top":0.055067837,"width":0.01662234,"height":0.03830806},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Services","depth":13,"bounds":{"left":0.39943483,"top":0.055067837,"width":0.01662234,"height":0.03830806},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"Search","depth":16,"bounds":{"left":0.41605717,"top":0.0622506,"width":0.17952128,"height":0.023942538},"role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Ask Amazon Q","depth":15,"bounds":{"left":0.5822806,"top":0.06464485,"width":0.009973404,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[Option+S]","depth":16,"bounds":{"left":0.56067157,"top":0.06743815,"width":0.023271276,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"CloudShell","depth":14,"bounds":{"left":0.8128325,"top":0.055067837,"width":0.015957447,"height":0.03830806},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Notifications (none available)","depth":15,"bounds":{"left":0.8287899,"top":0.058260176,"width":0.01662234,"height":0.031923383},"help_text":"Notifications","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Help & support","depth":15,"bounds":{"left":0.84541225,"top":0.055067837,"width":0.01662234,"height":0.03830806},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Settings","depth":15,"bounds":{"left":0.86203456,"top":0.055067837,"width":0.01662234,"height":0.03830806},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"United States (Ohio)","depth":15,"bounds":{"left":0.8786569,"top":0.055067837,"width":0.053690158,"height":0.03830806},"value":"United States (Ohio)","help_text":"United States (Ohio)","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"United States (Ohio)","depth":17,"bounds":{"left":0.8843085,"top":0.06823623,"width":0.03706782,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"PROD","depth":15,"bounds":{"left":0.93234706,"top":0.055067837,"width":0.067652926,"height":0.03830806},"help_text":"Production_View_Only @ jiminny","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Account ID: 4103-4619-5943","depth":19,"bounds":{"left":0.9353391,"top":0.057063047,"width":0.05435505,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PROD","depth":18,"bounds":{"left":0.98204786,"top":0.075418994,"width":0.010638298,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"EC2 EC2","depth":16,"bounds":{"left":0.36353058,"top":0.09577015,"width":0.020279255,"height":0.022346368},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EC2","depth":18,"bounds":{"left":0.37416887,"top":0.1009577,"width":0.006981383,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Elastic Container Service Elastic Container Service","depth":16,"bounds":{"left":0.38380983,"top":0.09577015,"width":0.057513297,"height":0.022346368},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Elastic Container Service","depth":18,"bounds":{"left":0.39444813,"top":0.1009577,"width":0.044215426,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"S3 S3","depth":16,"bounds":{"left":0.44132313,"top":0.09577015,"width":0.017952127,"height":0.022346368},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"S3","depth":18,"bounds":{"left":0.45196143,"top":0.1009577,"width":0.004654255,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CodeDeploy CodeDeploy","depth":16,"bounds":{"left":0.45927528,"top":0.09577015,"width":0.03507314,"height":0.022346368},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CodeDeploy","depth":18,"bounds":{"left":0.46991357,"top":0.1009577,"width":0.021775266,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudWatch CloudWatch","depth":16,"bounds":{"left":0.4943484,"top":0.09577015,"width":0.03523936,"height":0.022346368},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":18,"bounds":{"left":0.5049867,"top":0.1009577,"width":0.021941489,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"ElastiCache ElastiCache","depth":16,"bounds":{"left":0.52958775,"top":0.09577015,"width":0.033909574,"height":0.022346368},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ElastiCache","depth":18,"bounds":{"left":0.54022604,"top":0.1009577,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Aurora and RDS Aurora and RDS","depth":16,"bounds":{"left":0.56349736,"top":0.09577015,"width":0.041888297,"height":0.022346368},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Aurora and RDS","depth":18,"bounds":{"left":0.57413566,"top":0.1009577,"width":0.028590426,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon OpenSearch Service Amazon OpenSearch Service","depth":16,"bounds":{"left":0.60538566,"top":0.09577015,"width":0.0631649,"height":0.022346368},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Amazon OpenSearch Service","depth":18,"bounds":{"left":0.61602396,"top":0.1009577,"width":0.051861703,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudFront CloudFront","depth":16,"bounds":{"left":0.66855055,"top":0.09577015,"width":0.033410903,"height":0.022346368},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudFront","depth":18,"bounds":{"left":0.67918885,"top":0.1009577,"width":0.020113032,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"MediaLive MediaLive","depth":16,"bounds":{"left":0.70196146,"top":0.09577015,"width":0.031416222,"height":0.022346368},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"MediaLive","depth":18,"bounds":{"left":0.71259975,"top":0.1009577,"width":0.018118352,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open side navigation","depth":13,"bounds":{"left":0.36619017,"top":0.12410215,"width":0.009973404,"height":0.023942538},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"CloudWatch","depth":14,"bounds":{"left":0.3801529,"top":0.1272945,"width":0.026928192,"height":0.017557861},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":16,"bounds":{"left":0.38081783,"top":0.1292897,"width":0.025598405,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Logs Insights","depth":14,"bounds":{"left":0.41771942,"top":0.12809257,"width":0.028590426,"height":0.015961692},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logs Insights","depth":16,"bounds":{"left":0.41771942,"top":0.1292897,"width":0.028590426,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Query definition","depth":26,"bounds":{"left":0.37832448,"top":0.0,"width":0.05036569,"height":0.01915403},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Query definition","depth":28,"bounds":{"left":0.36968085,"top":0.0,"width":0.05900931,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Info : Query definition","depth":27,"bounds":{"left":0.43134972,"top":0.0,"width":0.0076462766,"height":0.011971269},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"5m (5 Minutes)","depth":27,"bounds":{"left":0.71276593,"top":0.0,"width":0.012134309,"height":0.015961692},"help_text":"5 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"30m (30 Minutes)","depth":27,"bounds":{"left":0.73254657,"top":0.0,"width":0.014960106,"height":0.015961692},"help_text":"30 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"1h (1 Hour)","depth":27,"bounds":{"left":0.75515294,"top":0.0,"width":0.010970744,"height":0.015961692},"help_text":"1 Hour","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"3h (3 Hours)","depth":27,"bounds":{"left":0.77360374,"top":0.0,"width":0.010804521,"height":0.015961692},"help_text":"3 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"12h (12 Hours)","depth":27,"bounds":{"left":0.79205453,"top":0.0,"width":0.013464096,"height":0.015961692},"help_text":"12 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Custom","depth":27,"bounds":{"left":0.8131649,"top":0.0,"width":0.024268618,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Custom","depth":29,"bounds":{"left":0.8131649,"top":0.0,"width":0.016289894,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Compare (Off)","depth":26,"bounds":{"left":0.84391624,"top":0.0,"width":0.046875,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":27,"bounds":{"left":0.85123,"top":0.0,"width":0.019946808,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.87117684,"top":0.0,"width":0.0028257978,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Off","depth":27,"bounds":{"left":0.87400264,"top":0.0,"width":0.0078125,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.88181514,"top":0.0,"width":0.0016622341,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Time zone UTC timezone","depth":26,"bounds":{"left":0.8931183,"top":0.0,"width":0.046043884,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"UTC timezone","depth":28,"bounds":{"left":0.89744014,"top":0.0,"width":0.029421542,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start tailing with selected log group (opens in a new tab)","depth":26,"bounds":{"left":0.9431516,"top":0.0,"width":0.048038565,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start tailing","depth":27,"bounds":{"left":0.95711434,"top":0.0,"width":0.026761968,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query scope","depth":28,"bounds":{"left":0.36968085,"top":0.0,"width":0.027094414,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Query scope Log group name","depth":27,"bounds":{"left":0.36968085,"top":0.0011971269,"width":0.06648936,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Log group name","depth":29,"bounds":{"left":0.37400267,"top":0.006783719,"width":0.034574468,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Select up to 50 log groups","depth":28,"bounds":{"left":0.44215426,"top":0.0011971269,"width":0.44132313,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show more chosen log groups","depth":27,"bounds":{"left":0.4418218,"top":0.077813245,"width":0.08377659,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Show more chosen log groups (+25)","depth":29,"bounds":{"left":0.44913563,"top":0.080207504,"width":0.07579787,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Browse","depth":28,"bounds":{"left":0.8874667,"top":0.00518755,"width":0.015292553,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":28,"bounds":{"left":0.9027593,"top":0.00518755,"width":0.0011635638,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Log Groups","depth":27,"bounds":{"left":0.9065825,"top":0.00518755,"width":0.025265958,"height":0.01396648},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"bounds":{"left":0.93450797,"top":0.00518755,"width":0.0011635638,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Facets","depth":27,"bounds":{"left":0.9383311,"top":0.00518755,"width":0.013796543,"height":0.01396648},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"bounds":{"left":0.95478725,"top":0.00518755,"width":0.0013297872,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Lookup tables","depth":27,"bounds":{"left":0.9587766,"top":0.00518755,"width":0.031083776,"height":0.01396648},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Undo","depth":28,"bounds":{"left":0.9453125,"top":0.23264167,"width":0.00930851,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Redo","depth":28,"bounds":{"left":0.9572806,"top":0.23264167,"width":0.00930851,"height":0.015961692},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Logs Insights QL","depth":29,"bounds":{"left":0.37533244,"top":0.26656026,"width":0.057679523,"height":0.025538707},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Query generator","depth":26,"bounds":{"left":0.43567154,"top":0.26296887,"width":0.05236037,"height":0.032721467},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Query generator","depth":28,"bounds":{"left":0.4476396,"top":0.27094972,"width":0.036402926,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fields","depth":28,"bounds":{"left":0.49867022,"top":0.27094972,"width":0.012799202,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saved and sample queries","depth":28,"bounds":{"left":0.52609706,"top":0.27094972,"width":0.05651596,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query commands","depth":28,"bounds":{"left":0.5972407,"top":0.27094972,"width":0.03856383,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Run query","depth":27,"bounds":{"left":0.36968085,"top":0.30606544,"width":0.03723404,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Cancel","depth":27,"bounds":{"left":0.40957448,"top":0.30606544,"width":0.02925532,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Save","depth":27,"bounds":{"left":0.44148937,"top":0.30606544,"width":0.024767287,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"History","depth":27,"bounds":{"left":0.5304189,"top":0.30606544,"width":0.030751329,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Completed. Query executed for","depth":28,"bounds":{"left":0.37632978,"top":0.3387869,"width":0.065990694,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"26 log groups.","depth":28,"bounds":{"left":0.44365028,"top":0.3387869,"width":0.03025266,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View log groups used in query","depth":28,"bounds":{"left":0.47506648,"top":0.3387869,"width":0.005319149,"height":0.01396648},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Logs (15)","depth":25,"bounds":{"left":0.36569148,"top":0.37470073,"width":0.03125,"height":0.035115723},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Logs","depth":27,"bounds":{"left":0.36968085,"top":0.38427773,"width":0.011469414,"height":0.015961692},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.38264626,"top":0.38427773,"width":0.0018284575,"height":0.015961692},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15","depth":27,"bounds":{"left":0.38447472,"top":0.38427773,"width":0.006150266,"height":0.015961692},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.390625,"top":0.38427773,"width":0.0019946808,"height":0.015961692},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Patterns (8)","depth":25,"bounds":{"left":0.40259308,"top":0.37470073,"width":0.03756649,"height":0.035115723},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Patterns","depth":27,"bounds":{"left":0.40658244,"top":0.38427773,"width":0.021110373,"height":0.015961692},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.42769283,"top":0.38427773,"width":0.0031582448,"height":0.015961692},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8","depth":27,"bounds":{"left":0.43085107,"top":0.38427773,"width":0.0031582448,"height":0.015961692},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.4340093,"top":0.38427773,"width":0.0018284575,"height":0.015961692},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Visualization","depth":25,"bounds":{"left":0.44581118,"top":0.37470073,"width":0.040724736,"height":0.035115723},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Visualization","depth":27,"bounds":{"left":0.44980052,"top":0.38427773,"width":0.032413565,"height":0.015961692},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Logs (15)","depth":26,"bounds":{"left":0.3693484,"top":0.42019153,"width":0.027759308,"height":0.01915403},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Logs (15)","depth":27,"bounds":{"left":0.3693484,"top":0.42019153,"width":0.027759308,"height":0.01915403},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize results","depth":26,"bounds":{"left":0.6599069,"top":0.41540304,"width":0.06216755,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize results","depth":27,"bounds":{"left":0.67386967,"top":0.42098963,"width":0.04089096,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Investigate","depth":28,"bounds":{"left":0.72473407,"top":0.41540304,"width":0.053025264,"height":0.025538707},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Investigate","depth":29,"bounds":{"left":0.7393617,"top":0.42098963,"width":0.02443484,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Share results","depth":26,"bounds":{"left":0.7804189,"top":0.41540304,"width":0.049867023,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Share results","depth":27,"bounds":{"left":0.7943817,"top":0.42098963,"width":0.028590426,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Export results","depth":28,"bounds":{"left":0.83294547,"top":0.41540304,"width":0.052027926,"height":0.025538707},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Export results","depth":29,"bounds":{"left":0.8402593,"top":0.42098963,"width":0.030751329,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add to dashboard","depth":26,"bounds":{"left":0.88763297,"top":0.41540304,"width":0.054022606,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Showing 15 of 15 records matched","depth":29,"bounds":{"left":0.62450135,"top":0.45530728,"width":0.080784574,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"11,743,819 records (2.7 GB) scanned in 6.1s @ 1,935,368 records/s (451.6 MB/s)","depth":29,"bounds":{"left":0.5802859,"top":0.47286513,"width":0.16921543,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Hide histogram","depth":26,"bounds":{"left":0.9637633,"top":0.4537111,"width":0.031083776,"height":0.03431764},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hide histogram","depth":27,"bounds":{"left":0.9637633,"top":0.4557063,"width":0.027759308,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Filter table results","depth":25,"bounds":{"left":0.36668882,"top":0.57302475,"width":0.21542554,"height":0.025538707},"help_text":"","placeholder":"Filter table results (case insensitive)...","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2026-04-21T16:18:23.207Z","depth":29,"bounds":{"left":0.38231382,"top":0.64964086,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:23] production.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":74049485,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":19003658,\"opportunity_id\":null,\"stage_id\":null} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.64964086,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:18:23.203Z","depth":29,"bounds":{"left":0.38231382,"top":0.6711891,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:23] production.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":74049485,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.6711891,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:18:23.202Z","depth":29,"bounds":{"left":0.38231382,"top":0.6927374,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:23] production.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":74049485} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.6927374,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:18:23.200Z","depth":29,"bounds":{"left":0.38231382,"top":0.71428573,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:23] production.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":74049485,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.71428573,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:18:22.732Z","depth":29,"bounds":{"left":0.38231382,"top":0.735834,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:22] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":74049485,\"team_id\":563,\"email\":\"ariela@getmobiz.com\"} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.735834,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:18:22.718Z","depth":29,"bounds":{"left":0.38231382,"top":0.7573823,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:22] production.INFO: [MatchActivityCrmData] Participants old state {\"activity\":74049485,\"participants\":[{\"id\":228313765,\"user_id\":28994,\"contact_id\":null,\"lead_id\":null},{\"id\":228313766,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.7573823,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:18:22.717Z","depth":29,"bounds":{"left":0.38231382,"top":0.77893054,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:22] production.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":74049485,\"remote_search\":true,\"set_configuration\":null,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":null,\"opportunity_id\":null,\"stage_id\":null}} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.77893054,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:52.682Z","depth":29,"bounds":{"left":0.38231382,"top":0.8004789,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:52] production.ERROR: [MatchActivityCrmData] Failed to match CRM data {\"activity\":74049485,\"remote_search\":true,\"exception\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:","depth":29,"bounds":{"left":0.44730717,"top":0.8004789,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:52.331Z","depth":29,"bounds":{"left":0.38231382,"top":0.82202715,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:52] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":74049485,\"team_id\":563,\"email\":\"ariela@getmobiz.com\"} {\"correlation_id\":\"3db09bd8-5f91-43f3-a13a-7f16d41813e3\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.82202715,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:52.308Z","depth":29,"bounds":{"left":0.38231382,"top":0.8435754,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:52] production.INFO: [MatchActivityCrmData] Participants old state {\"activity\":74049485,\"participants\":[{\"id\":228313765,\"user_id\":28994,\"contact_id\":null,\"lead_id\":null},{\"id\":228313766,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"3db09bd8-5f91-43f3-a13a-7f16d41813e3\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.8435754,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:52.306Z","depth":29,"bounds":{"left":0.38231382,"top":0.8651237,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:52] production.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":74049485,\"remote_search\":true,\"set_configuration\":null,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":null,\"opportunity_id\":null,\"stage_id\":null}} {\"correlation_id\":\"3db09bd8-5f91-43f3-a13a-7f16d41813e3\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.8651237,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:22.246Z","depth":29,"bounds":{"left":0.38231382,"top":0.88667196,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:22] production.ERROR: [MatchActivityCrmData] Failed to match CRM data {\"activity\":74049485,\"remote_search\":true,\"exception\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:","depth":29,"bounds":{"left":0.44730717,"top":0.88667196,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:21.911Z","depth":29,"bounds":{"left":0.38231382,"top":0.9082203,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:21] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":74049485,\"team_id\":563,\"email\":\"ariela@getmobiz.com\"} {\"correlation_id\":\"249bfb31-785c-4c1b-9937-5416b8975345\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.9082203,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:21.879Z","depth":29,"bounds":{"left":0.38231382,"top":0.92976856,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:21] production.INFO: [MatchActivityCrmData] Participants old state {\"activity\":74049485,\"participants\":[{\"id\":228313765,\"user_id\":28994,\"contact_id\":null,\"lead_id\":null},{\"id\":228313766,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"249bfb31-785c-4c1b-9937-5416b8975345\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.92976856,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:21.875Z","depth":29,"bounds":{"left":0.38231382,"top":0.95131683,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:21] production.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":74049485,\"remote_search\":true,\"set_configuration\":null,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":null,\"opportunity_id\":null,\"stage_id\":null}} {\"correlation_id\":\"249bfb31-785c-4c1b-9937-5416b8975345\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.95131683,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:18:23.207Z","depth":29,"bounds":{"left":0.38231382,"top":0.64964086,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:18:23.203Z","depth":29,"bounds":{"left":0.38231382,"top":0.6711891,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:18:23.202Z","depth":29,"bounds":{"left":0.38231382,"top":0.6927374,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:18:23.200Z","depth":29,"bounds":{"left":0.38231382,"top":0.71428573,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:18:22.732Z","depth":29,"bounds":{"left":0.38231382,"top":0.735834,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:18:22.718Z","depth":29,"bounds":{"left":0.38231382,"top":0.7573823,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:18:22.717Z","depth":29,"bounds":{"left":0.38231382,"top":0.77893054,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:52.682Z","depth":29,"bounds":{"left":0.38231382,"top":0.8004789,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:52.331Z","depth":29,"bounds":{"left":0.38231382,"top":0.82202715,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:52.308Z","depth":29,"bounds":{"left":0.38231382,"top":0.8435754,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:52.306Z","depth":29,"bounds":{"left":0.38231382,"top":0.8651237,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:22.246Z","depth":29,"bounds":{"left":0.38231382,"top":0.88667196,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:21.911Z","depth":29,"bounds":{"left":0.38231382,"top":0.9082203,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:21.879Z","depth":29,"bounds":{"left":0.38231382,"top":0.92976856,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-21T16:16:21.875Z","depth":29,"bounds":{"left":0.38231382,"top":0.95131683,"width":0.057513297,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:23] production.INFO: [MatchActivityCrmData] Successfully matched CRM data {\"activity\":74049485,\"remote_search\":true,\"lead_id\":null,\"contact_id\":null,\"account_id\":19003658,\"opportunity_id\":null,\"stage_id\":null} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.64964086,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:23] production.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {\"entityType\":\"activities\",\"entityId\":74049485,\"collectionKey\":\"activities-for-update-priority\",\"withPriority\":true} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.6711891,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:23] production.INFO: [ EsUpdateTarget ] Update single target {\"target\":\"activities\",\"purpose\":\"searchable-observer-update\",\"entityId\":74049485} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.6927374,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:23] production.INFO: [CrmActivityService] CRM matching completed {\"activity_id\":74049485,\"participants_processed\":2,\"exact_matches\":0,\"domain_matches\":1,\"best_match_found\":true} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.71428573,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:22] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":74049485,\"team_id\":563,\"email\":\"ariela@getmobiz.com\"} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.735834,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:22] production.INFO: [MatchActivityCrmData] Participants old state {\"activity\":74049485,\"participants\":[{\"id\":228313765,\"user_id\":28994,\"contact_id\":null,\"lead_id\":null},{\"id\":228313766,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.7573823,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:18:22] production.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":74049485,\"remote_search\":true,\"set_configuration\":null,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":null,\"opportunity_id\":null,\"stage_id\":null}} {\"correlation_id\":\"bd216559-1cca-4c38-832a-fc934177832a\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.77893054,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:52] production.ERROR: [MatchActivityCrmData] Failed to match CRM data {\"activity\":74049485,\"remote_search\":true,\"exception\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:","depth":29,"bounds":{"left":0.44730717,"top":0.8004789,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:52] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":74049485,\"team_id\":563,\"email\":\"ariela@getmobiz.com\"} {\"correlation_id\":\"3db09bd8-5f91-43f3-a13a-7f16d41813e3\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.82202715,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:52] production.INFO: [MatchActivityCrmData] Participants old state {\"activity\":74049485,\"participants\":[{\"id\":228313765,\"user_id\":28994,\"contact_id\":null,\"lead_id\":null},{\"id\":228313766,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"3db09bd8-5f91-43f3-a13a-7f16d41813e3\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.8435754,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:52] production.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":74049485,\"remote_search\":true,\"set_configuration\":null,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":null,\"opportunity_id\":null,\"stage_id\":null}} {\"correlation_id\":\"3db09bd8-5f91-43f3-a13a-7f16d41813e3\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.8651237,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:22] production.ERROR: [MatchActivityCrmData] Failed to match CRM data {\"activity\":74049485,\"remote_search\":true,\"exception\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:","depth":29,"bounds":{"left":0.44730717,"top":0.88667196,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:21] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {\"activity_id\":74049485,\"team_id\":563,\"email\":\"ariela@getmobiz.com\"} {\"correlation_id\":\"249bfb31-785c-4c1b-9937-5416b8975345\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.9082203,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:21] production.INFO: [MatchActivityCrmData] Participants old state {\"activity\":74049485,\"participants\":[{\"id\":228313765,\"user_id\":28994,\"contact_id\":null,\"lead_id\":null},{\"id\":228313766,\"user_id\":null,\"contact_id\":null,\"lead_id\":null}]} {\"correlation_id\":\"249bfb31-785c-4c1b-9937-5416b8975345\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.92976856,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-21 16:16:21] production.INFO: [MatchActivityCrmData] Starting CRM data matching {\"activity\":74049485,\"remote_search\":true,\"set_configuration\":null,\"old_state\":{\"lead_id\":null,\"contact_id\":null,\"account_id\":null,\"opportunity_id\":null,\"stage_id\":null}} {\"correlation_id\":\"249bfb31-785c-4c1b-9937-5416b8975345\",\"trace_id\":\"5409999d-a378-47e8-a246-3e4b95c83127\"}","depth":29,"bounds":{"left":0.44730717,"top":0.95131683,"width":0.55269283,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab","depth":29,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-560100324133461643
|
9029552126040449043
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
[JY-20372] AI Reports > Empty page design and promotion - Jira
[JY-20372] AI Reports > Empty page design and promotion - Jira
Jiminny MCP Connector - Product - Confluence
Jiminny MCP Connector - Product - Confluence
CRM issues - Apr 22 - Chat
CRM issues - Apr 22 - Chat
[JY-20500] Batch initial sync for Salesforce - Jira
[JY-20500] Batch initial sync for Salesforce - Jira
Feed — jiminny — Sentry
Feed — jiminny — Sentry
Jiminny
Jiminny
Pipelines - /app
Pipelines - /app
Formalize
Formalize
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
Search results: calendar | Jiminny Help Center
Search results: calendar | Jiminny Help Center
Jiminny
Jiminny
Jiminny
Jiminny
Jiminny
Jiminny
Edit - Engineering - Confluence
Edit - Engineering - Confluence
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {"status":"error","message":"You have reached your secondly limit.","errorType":"RATE_LIMIT
Workers | Datadog
Workers | Datadog
Pull requests · jiminny/app
Pull requests · jiminny/app
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom
Custom
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Completed. Query executed for
26 log groups.
View log groups used in query
Logs (15)
Logs
(
15
)
Patterns (8)
Patterns
(
8
)
Visualization
Visualization
Logs (15)
Logs (15)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
Showing 15 of 15 records matched
11,743,819 records (2.7 GB) scanned in 6.1s @ 1,935,368 records/s (451.6 MB/s)
Hide histogram
Hide histogram
Filter table results
2026-04-21T16:18:23.207Z
[2026-04-21 16:18:23] production.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":74049485,"remote_search":true,"lead_id":null,"contact_id":null,"account_id":19003658,"opportunity_id":null,"stage_id":null} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:23.203Z
[2026-04-21 16:18:23] production.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":74049485,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:23.202Z
[2026-04-21 16:18:23] production.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":74049485} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:23.200Z
[2026-04-21 16:18:23] production.INFO: [CrmActivityService] CRM matching completed {"activity_id":74049485,"participants_processed":2,"exact_matches":0,"domain_matches":1,"best_match_found":true} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:22.732Z
[2026-04-21 16:18:22] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":74049485,"team_id":563,"email":"[EMAIL]"} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:22.718Z
[2026-04-21 16:18:22] production.INFO: [MatchActivityCrmData] Participants old state {"activity":74049485,"participants":[{"id":228313765,"user_id":28994,"contact_id":null,"lead_id":null},{"id":228313766,"user_id":null,"contact_id":null,"lead_id":null}]} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:22.717Z
[2026-04-21 16:18:22] production.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":74049485,"remote_search":true,"set_configuration":null,"old_state":{"lead_id":null,"contact_id":null,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:52.682Z
[2026-04-21 16:16:52] production.ERROR: [MatchActivityCrmData] Failed to match CRM data {"activity":74049485,"remote_search":true,"exception":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:52.331Z
[2026-04-21 16:16:52] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":74049485,"team_id":563,"email":"[EMAIL]"} {"correlation_id":"3db09bd8-5f91-43f3-a13a-7f16d41813e3","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:52.308Z
[2026-04-21 16:16:52] production.INFO: [MatchActivityCrmData] Participants old state {"activity":74049485,"participants":[{"id":228313765,"user_id":28994,"contact_id":null,"lead_id":null},{"id":228313766,"user_id":null,"contact_id":null,"lead_id":null}]} {"correlation_id":"3db09bd8-5f91-43f3-a13a-7f16d41813e3","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:52.306Z
[2026-04-21 16:16:52] production.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":74049485,"remote_search":true,"set_configuration":null,"old_state":{"lead_id":null,"contact_id":null,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"3db09bd8-5f91-43f3-a13a-7f16d41813e3","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:22.246Z
[2026-04-21 16:16:22] production.ERROR: [MatchActivityCrmData] Failed to match CRM data {"activity":74049485,"remote_search":true,"exception":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:21.911Z
[2026-04-21 16:16:21] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":74049485,"team_id":563,"email":"[EMAIL]"} {"correlation_id":"249bfb31-785c-4c1b-9937-5416b8975345","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:21.879Z
[2026-04-21 16:16:21] production.INFO: [MatchActivityCrmData] Participants old state {"activity":74049485,"participants":[{"id":228313765,"user_id":28994,"contact_id":null,"lead_id":null},{"id":228313766,"user_id":null,"contact_id":null,"lead_id":null}]} {"correlation_id":"249bfb31-785c-4c1b-9937-5416b8975345","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:16:21.875Z
[2026-04-21 16:16:21] production.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":74049485,"remote_search":true,"set_configuration":null,"old_state":{"lead_id":null,"contact_id":null,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"249bfb31-785c-4c1b-9937-5416b8975345","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab
410346195943:worker-analytics
2026-04-21T16:18:23.207Z
2026-04-21T16:18:23.203Z
2026-04-21T16:18:23.202Z
2026-04-21T16:18:23.200Z
2026-04-21T16:18:22.732Z
2026-04-21T16:18:22.718Z
2026-04-21T16:18:22.717Z
2026-04-21T16:16:52.682Z
2026-04-21T16:16:52.331Z
2026-04-21T16:16:52.308Z
2026-04-21T16:16:52.306Z
2026-04-21T16:16:22.246Z
2026-04-21T16:16:21.911Z
2026-04-21T16:16:21.879Z
2026-04-21T16:16:21.875Z
[2026-04-21 16:18:23] production.INFO: [MatchActivityCrmData] Successfully matched CRM data {"activity":74049485,"remote_search":true,"lead_id":null,"contact_id":null,"account_id":19003658,"opportunity_id":null,"stage_id":null} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:18:23] production.INFO: [ AsyncUpdateElasticSearch ] Entity added to Redis list {"entityType":"activities","entityId":74049485,"collectionKey":"activities-for-update-priority","withPriority":true} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:18:23] production.INFO: [ EsUpdateTarget ] Update single target {"target":"activities","purpose":"searchable-observer-update","entityId":74049485} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:18:23] production.INFO: [CrmActivityService] CRM matching completed {"activity_id":74049485,"participants_processed":2,"exact_matches":0,"domain_matches":1,"best_match_found":true} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:18:22] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":74049485,"team_id":563,"email":"[EMAIL]"} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:18:22] production.INFO: [MatchActivityCrmData] Participants old state {"activity":74049485,"participants":[{"id":228313765,"user_id":28994,"contact_id":null,"lead_id":null},{"id":228313766,"user_id":null,"contact_id":null,"lead_id":null}]} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:18:22] production.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":74049485,"remote_search":true,"set_configuration":null,"old_state":{"lead_id":null,"contact_id":null,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"bd216559-1cca-4c38-832a-fc934177832a","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:16:52] production.ERROR: [MatchActivityCrmData] Failed to match CRM data {"activity":74049485,"remote_search":true,"exception":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
[2026-04-21 16:16:52] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":74049485,"team_id":563,"email":"[EMAIL]"} {"correlation_id":"3db09bd8-5f91-43f3-a13a-7f16d41813e3","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:16:52] production.INFO: [MatchActivityCrmData] Participants old state {"activity":74049485,"participants":[{"id":228313765,"user_id":28994,"contact_id":null,"lead_id":null},{"id":228313766,"user_id":null,"contact_id":null,"lead_id":null}]} {"correlation_id":"3db09bd8-5f91-43f3-a13a-7f16d41813e3","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:16:52] production.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":74049485,"remote_search":true,"set_configuration":null,"old_state":{"lead_id":null,"contact_id":null,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"3db09bd8-5f91-43f3-a13a-7f16d41813e3","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:16:22] production.ERROR: [MatchActivityCrmData] Failed to match CRM data {"activity":74049485,"remote_search":true,"exception":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
[2026-04-21 16:16:21] production.INFO: [CrmActivityService] Email domain belongs to the team, skipping crm lookup {"activity_id":74049485,"team_id":563,"email":"[EMAIL]"} {"correlation_id":"249bfb31-785c-4c1b-9937-5416b8975345","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:16:21] production.INFO: [MatchActivityCrmData] Participants old state {"activity":74049485,"participants":[{"id":228313765,"user_id":28994,"contact_id":null,"lead_id":null},{"id":228313766,"user_id":null,"contact_id":null,"lead_id":null}]} {"correlation_id":"249bfb31-785c-4c1b-9937-5416b8975345","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
[2026-04-21 16:16:21] production.INFO: [MatchActivityCrmData] Starting CRM data matching {"activity":74049485,"remote_search":true,"set_configuration":null,"old_state":{"lead_id":null,"contact_id":null,"account_id":null,"opportunity_id":null,"stage_id":null}} {"correlation_id":"249bfb31-785c-4c1b-9937-5416b8975345","trace_id":"5409999d-a378-47e8-a246-3e4b95c83127"}
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/25c5c254a05e48e88b31239aa769fc81 Opens in a new tab
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
worker-analytics/worker-analytics/8afbcb0d2cf74858ac45da2fe15b4392 Opens in a new tab
worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab
worker-analytics/worker-analytics/27b9573e83bc45b9b132a2692bd7d530 Opens in a new tab...
|
70224
|
|
51863
|
1121
|
52
|
2026-04-20T06:24:22.249942+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-20/1776 /Users/lukas/.screenpipe/data/data/2026-04-20/1776666262249_m2.jpg...
|
Firefox
|
Product Growth Platform | Userpilot — Work
|
1
|
userpilot.com
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
[JY-18909] [Part2] Automated reports with Ask Jimi [JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
New Tab
New Tab
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Close bookmarks (⌘B)
Bookmarks
Bookmarks
Close sidebar
Search bookmarks
Userpilot
Platform
Solutions
Pricing
Pricing
Integrations
Integrations
Resources
Resources
Customers
Customers
Free Trial
Free Trial
Log in
Log in
Get a Demo
Get a Demo
Drive Product Growth with
Drive Product Growth with
User Insights.
User Engagement.
User Feedback.
Leverage user insights & in-app engagement to drive adoption, retention, and revenue.
Enter your email address
Get a Demo
coming soon Userpilot AI
coming soon
Userpilot AI
In-app Engagement
In-app Engagement
Product Analytics
Product Analytics
User Feedback
User Feedback
Session Replay
Session Replay
Join 1,000+ Companies Accelerating Product Growth With Userpilot.
Introducing Lia
Userpilot’s AI Agent for Product Growth
Userpilot’s AI Agent for Product Growth
Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.
Learn more about Lia
Learn more about Lia
User Onboarding
User Onboarding
Guide new users through your product and reduce time-to-value.
Help existing users discover new features contextually.
See User Onboarding Solutions
See User Onboarding Solutions
Product Analytics
Product Analytics
Understand user behavior across the product journey.
Generate custom reports to answer any product question.
See Analytics Features
See Analytics Features
User Feedback
User Feedback
Capture and analyze user sentiment at scale.
Understand how your users really feel with contextual Microsurveys.
See User Feedback Tools
See User Feedback Tools
Session Replay
Session Replay
Learn how users interact with your product.
Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.
See Session Replay Features
See Session Replay Features
Userpilot for Mobile
Userpilot for Mobile
Use mobile-first UI patterns.
Onboard users, run surveys, and track product metrics on native mobile devices.
Explore Mobile Features
Explore Mobile Features
Rally Your Whole Team Around Your Product Growth Goals.
Rally Your Whole Team Around Your Product Growth Goals.
Start 14 Days Free Trial
Start 14 Days Free Trial
No credit card required
Kontentino improved New User Activation Rate by 10% in 1 month
Kontentino improved New User Activation Rate by 10% in 1 month
“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”
Integrate Userpilot with your favorite tech stack
Integrate Userpilot with your favorite tech stack
Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.
Learn More
Learn More
Unlock the Power of Product-Led Growth
Unlock the Power of Product-Led Growth
Best practices to help you
activate more users, increase user engagement
and
drive more product growth.
Userpilot Blog Learn about product growth, good UX and the latest trends in product management.
Userpilot Blog
Userpilot Blog
Learn about product growth, good UX and the latest trends in product management.
Read
Read
Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.
Upcoming Webinars
Upcoming Webinars
Upcoming live webinars, on-demand videos and webcasts.
Watch
Watch
Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Product Drive Conference
Product Drive Conference
Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Connect
Connect
Take Your Product Experience to the Next Level
Get a Demo
Get a Demo
Product
Product
Product Analytics
Product Analytics
User Engagement
User Engagement
User Feedback
User Feedback
Company
Company
Events
Events
Careers
Careers
Customers
Customers
Contact Us
Contact Us
About Us
About Us
Use Cases
Use Cases
User Onboarding
User Onboarding
Product Adoption
Product Adoption
Customer Retention
Customer Retention
Product Led Growth
Product Led Growth
In-App Support
In-App Support
Roles
Roles
Product Growth
Product Growth
Product Marketing
Product Marketing
Product Management
Product Management
UX Design
UX Design
Resources
Resources
Blog
Blog
Product Adoption School
Product Adoption School
Product Drive
Product Drive
SaaS Onboarding Research
SaaS Onboarding Research
Case Studies
Case Studies
Sitemap
Sitemap
Support
Support
Help Center
Help Center
System Status
System Status
Trust Center
Trust Center
Read more
Read more
User Onboarding
User Onboarding
Product Tours
Product Tours
Customer Success
Customer Success
User Behavior Tracking
User Behavior Tracking
In-App Guidance
In-App Guidance
Microsurveys for SaaS Guide
Microsurveys for SaaS Guide
Interactive User Guides
Interactive User Guides
© 2026 Userpilot. All rights reserved
Terms of Use
Terms of Use...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":4,"bounds":{"left":0.0018284575,"top":0.0518755,"width":0.07596409,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.09497207,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.10614525,"width":0.10106383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.12769353,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.13886672,"width":0.19963431,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.16041501,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.17158818,"width":0.15525267,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":4,"bounds":{"left":0.0,"top":0.19313647,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.20430966,"width":0.06981383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":4,"bounds":{"left":0.0,"top":0.22585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.23703113,"width":0.10688165,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.2585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.2697526,"width":0.12915559,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.29130086,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.013297873,"top":0.30247405,"width":0.014960106,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Product Growth Platform | Userpilot","depth":4,"bounds":{"left":0.0,"top":0.32402235,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Product Growth Platform | Userpilot","depth":5,"bounds":{"left":0.013297873,"top":0.33519554,"width":0.06200133,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.3312051,"width":0.007978723,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.35834,"width":0.07413564,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Bookmarks","depth":5,"bounds":{"left":0.083277926,"top":0.06943336,"width":0.026761968,"height":0.014764565},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bookmarks","depth":6,"bounds":{"left":0.083277926,"top":0.06943336,"width":0.026761968,"height":0.014764565},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close sidebar","depth":6,"bounds":{"left":0.1783577,"top":0.06424581,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"Search bookmarks","depth":7,"bounds":{"left":0.082446806,"top":0.09976058,"width":0.107546546,"height":0.025538707},"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Userpilot","depth":9,"bounds":{"left":0.35688165,"top":0.09936153,"width":0.07197473,"height":0.023144454},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform","depth":13,"bounds":{"left":0.4730718,"top":0.103751,"width":0.019115692,"height":0.014764565},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Solutions","depth":13,"bounds":{"left":0.5021609,"top":0.103751,"width":0.020777926,"height":0.014764565},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pricing","depth":12,"bounds":{"left":0.53291225,"top":0.08140463,"width":0.01512633,"height":0.05905826},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pricing","depth":13,"bounds":{"left":0.53291225,"top":0.103751,"width":0.01512633,"height":0.014764565},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Integrations","depth":12,"bounds":{"left":0.55801195,"top":0.08140463,"width":0.026761968,"height":0.05905826},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Integrations","depth":13,"bounds":{"left":0.55801195,"top":0.103751,"width":0.026761968,"height":0.014764565},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Resources","depth":12,"bounds":{"left":0.59474736,"top":0.08140463,"width":0.023271276,"height":0.05905826},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Resources","depth":13,"bounds":{"left":0.59474736,"top":0.103751,"width":0.023271276,"height":0.014764565},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customers","depth":12,"bounds":{"left":0.62799203,"top":0.08140463,"width":0.02443484,"height":0.05905826},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customers","depth":13,"bounds":{"left":0.62799203,"top":0.103751,"width":0.02443484,"height":0.014764565},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Free Trial","depth":12,"bounds":{"left":0.66240025,"top":0.08140463,"width":0.019115692,"height":0.05905826},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Free Trial","depth":13,"bounds":{"left":0.66240025,"top":0.103751,"width":0.019115692,"height":0.014764565},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Log in","depth":12,"bounds":{"left":0.77443486,"top":0.104948126,"width":0.012965426,"height":0.014764565},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Log in","depth":13,"bounds":{"left":0.77443486,"top":0.104948126,"width":0.012965426,"height":0.014764565},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Get a Demo","depth":12,"bounds":{"left":0.79504657,"top":0.09457303,"width":0.043882977,"height":0.035514764},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Get a Demo","depth":13,"bounds":{"left":0.80369014,"top":0.104948126,"width":0.026595745,"height":0.014764565},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Drive Product Growth with","depth":9,"bounds":{"left":0.49517953,"top":0.19553073,"width":0.2052859,"height":0.047885075},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Drive Product Growth with","depth":10,"bounds":{"left":0.49517953,"top":0.19513169,"width":0.2052859,"height":0.04868316},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Insights.","depth":11,"bounds":{"left":0.545379,"top":0.2509976,"width":0.10488697,"height":0.04868316},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Engagement.","depth":11,"bounds":{"left":0.52609706,"top":0.2669593,"width":0.1434508,"height":0.04868316},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Feedback.","depth":11,"bounds":{"left":0.5365692,"top":0.2669593,"width":0.12250665,"height":0.04868316},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Leverage user insights & in-app engagement to drive adoption, retention, and revenue.","depth":10,"bounds":{"left":0.47739363,"top":0.32442138,"width":0.2408577,"height":0.017557861},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Enter your email address","depth":14,"bounds":{"left":0.52244014,"top":0.37988827,"width":0.099734046,"height":0.035913806},"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Get a Demo","depth":11,"bounds":{"left":0.6271609,"top":0.37988827,"width":0.046043884,"height":0.035913806},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"coming soon Userpilot AI","depth":10,"bounds":{"left":0.46226728,"top":0.45251396,"width":0.035904255,"height":0.014764565},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"coming soon","depth":12,"bounds":{"left":0.46708778,"top":0.42817238,"width":0.026097074,"height":0.0131683955},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot AI","depth":11,"bounds":{"left":0.47124335,"top":0.45291302,"width":0.025598405,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"In-app Engagement","depth":10,"bounds":{"left":0.50947475,"top":0.4521149,"width":0.053690158,"height":0.015163607},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-app Engagement","depth":11,"bounds":{"left":0.517121,"top":0.45291302,"width":0.044714097,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Product Analytics","depth":10,"bounds":{"left":0.5746343,"top":0.4521149,"width":0.04886968,"height":0.015163607},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Analytics","depth":11,"bounds":{"left":0.5822806,"top":0.45291302,"width":0.039893616,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"User Feedback","depth":10,"bounds":{"left":0.6349734,"top":0.45251396,"width":0.04338431,"height":0.014764565},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":11,"bounds":{"left":0.64261967,"top":0.45291302,"width":0.034408245,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Session Replay","depth":10,"bounds":{"left":0.68982714,"top":0.45251396,"width":0.043550532,"height":0.014764565},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Session Replay","depth":11,"bounds":{"left":0.6974734,"top":0.45291302,"width":0.034574468,"height":0.01396648},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Join 1,000+ Companies Accelerating Product Growth With Userpilot.","depth":10,"bounds":{"left":0.48055187,"top":0.6624102,"width":0.23454122,"height":0.022346368},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Introducing Lia","depth":13,"bounds":{"left":0.37416887,"top":0.9952115,"width":0.032912236,"height":0.004788518},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Userpilot’s AI Agent for Product Growth","depth":11,"bounds":{"left":0.36120346,"top":1.0,"width":0.26313165,"height":-0.029928207},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot’s AI Agent for Product Growth","depth":12,"bounds":{"left":0.36120346,"top":1.0,"width":0.17869017,"height":-0.029928207},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.","depth":12,"bounds":{"left":0.36120346,"top":1.0,"width":0.23520611,"height":-0.07422185},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about Lia","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about Lia","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"User Onboarding","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Onboarding","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Guide new users through your product and reduce time-to-value.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Help existing users discover new features contextually.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See User Onboarding Solutions","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See User Onboarding Solutions","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product Analytics","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product Analytics","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Understand user behavior across the product journey.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Generate custom reports to answer any product question.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See Analytics Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See Analytics Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"User Feedback","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Feedback","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Capture and analyze user sentiment at scale.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Understand how your users really feel with contextual Microsurveys.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See User Feedback Tools","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See User Feedback Tools","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Session Replay","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Session Replay","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn how users interact with your product.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See Session Replay Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See Session Replay Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Userpilot for Mobile","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot for Mobile","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use mobile-first UI patterns.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Onboard users, run surveys, and track product metrics on native mobile devices.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore Mobile Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore Mobile Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Rally Your Whole Team Around Your Product Growth Goals.","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Rally Your Whole Team Around Your Product Growth Goals.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Start 14 Days Free Trial","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start 14 Days Free Trial","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No credit card required","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Kontentino improved New User Activation Rate by 10% in 1 month","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Kontentino improved New User Activation Rate by 10% in 1 month","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Integrate Userpilot with your favorite tech stack","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Integrate Userpilot with your favorite tech stack","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn More","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn More","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Unlock the Power of Product-Led Growth","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unlock the Power of Product-Led Growth","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Best practices to help you","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"activate more users, increase user engagement","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"drive more product growth.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Userpilot Blog Learn about product growth, good UX and the latest trends in product management.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Userpilot Blog","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot Blog","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn about product growth, good UX and the latest trends in product management.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Read","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Upcoming Webinars","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upcoming Webinars","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upcoming live webinars, on-demand videos and webcasts.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Watch","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Watch","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Product Drive Conference","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product Drive Conference","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn from industry leaders and stay up-to-date on the latest trends in product growth.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Connect","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Connect","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Take Your Product Experience to the Next Level","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Get a Demo","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Get a Demo","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Analytics","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Analytics","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Engagement","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Engagement","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Feedback","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Company","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Company","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Events","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Events","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Careers","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Careers","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customers","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customers","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Contact Us","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Contact Us","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"About Us","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"About Us","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Use Cases","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use Cases","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Onboarding","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Onboarding","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Adoption","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Adoption","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customer Retention","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer Retention","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Led Growth","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Led Growth","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"In-App Support","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-App Support","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Roles","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Roles","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Growth","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Growth","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Marketing","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Marketing","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Management","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Management","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"UX Design","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"UX Design","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Resources","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resources","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Blog","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Blog","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Adoption School","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Adoption School","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Drive","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Drive","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SaaS Onboarding Research","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SaaS Onboarding Research","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Case Studies","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Case Studies","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sitemap","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sitemap","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Support","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Support","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Help Center","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help Center","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"System Status","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"System Status","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Trust Center","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Trust Center","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Read more","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Read more","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Onboarding","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Onboarding","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Tours","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Tours","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customer Success","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer Success","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Behavior Tracking","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Behavior Tracking","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"In-App Guidance","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-App Guidance","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Microsurveys for SaaS Guide","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Microsurveys for SaaS Guide","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Interactive User Guides","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Interactive User Guides","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"© 2026 Userpilot. All rights reserved","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Terms of Use","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Terms of Use","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
1081373228739605484
|
9029000526129998178
|
visual_change
|
accessibility
|
NULL
|
[JY-18909] [Part2] Automated reports with Ask Jimi [JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
Ask Jiminny Reports by nikolay-yankov · Pull Request #11894 · jiminny/app
New Tab
New Tab
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Close bookmarks (⌘B)
Bookmarks
Bookmarks
Close sidebar
Search bookmarks
Userpilot
Platform
Solutions
Pricing
Pricing
Integrations
Integrations
Resources
Resources
Customers
Customers
Free Trial
Free Trial
Log in
Log in
Get a Demo
Get a Demo
Drive Product Growth with
Drive Product Growth with
User Insights.
User Engagement.
User Feedback.
Leverage user insights & in-app engagement to drive adoption, retention, and revenue.
Enter your email address
Get a Demo
coming soon Userpilot AI
coming soon
Userpilot AI
In-app Engagement
In-app Engagement
Product Analytics
Product Analytics
User Feedback
User Feedback
Session Replay
Session Replay
Join 1,000+ Companies Accelerating Product Growth With Userpilot.
Introducing Lia
Userpilot’s AI Agent for Product Growth
Userpilot’s AI Agent for Product Growth
Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.
Learn more about Lia
Learn more about Lia
User Onboarding
User Onboarding
Guide new users through your product and reduce time-to-value.
Help existing users discover new features contextually.
See User Onboarding Solutions
See User Onboarding Solutions
Product Analytics
Product Analytics
Understand user behavior across the product journey.
Generate custom reports to answer any product question.
See Analytics Features
See Analytics Features
User Feedback
User Feedback
Capture and analyze user sentiment at scale.
Understand how your users really feel with contextual Microsurveys.
See User Feedback Tools
See User Feedback Tools
Session Replay
Session Replay
Learn how users interact with your product.
Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.
See Session Replay Features
See Session Replay Features
Userpilot for Mobile
Userpilot for Mobile
Use mobile-first UI patterns.
Onboard users, run surveys, and track product metrics on native mobile devices.
Explore Mobile Features
Explore Mobile Features
Rally Your Whole Team Around Your Product Growth Goals.
Rally Your Whole Team Around Your Product Growth Goals.
Start 14 Days Free Trial
Start 14 Days Free Trial
No credit card required
Kontentino improved New User Activation Rate by 10% in 1 month
Kontentino improved New User Activation Rate by 10% in 1 month
“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”
Integrate Userpilot with your favorite tech stack
Integrate Userpilot with your favorite tech stack
Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.
Learn More
Learn More
Unlock the Power of Product-Led Growth
Unlock the Power of Product-Led Growth
Best practices to help you
activate more users, increase user engagement
and
drive more product growth.
Userpilot Blog Learn about product growth, good UX and the latest trends in product management.
Userpilot Blog
Userpilot Blog
Learn about product growth, good UX and the latest trends in product management.
Read
Read
Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.
Upcoming Webinars
Upcoming Webinars
Upcoming live webinars, on-demand videos and webcasts.
Watch
Watch
Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Product Drive Conference
Product Drive Conference
Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Connect
Connect
Take Your Product Experience to the Next Level
Get a Demo
Get a Demo
Product
Product
Product Analytics
Product Analytics
User Engagement
User Engagement
User Feedback
User Feedback
Company
Company
Events
Events
Careers
Careers
Customers
Customers
Contact Us
Contact Us
About Us
About Us
Use Cases
Use Cases
User Onboarding
User Onboarding
Product Adoption
Product Adoption
Customer Retention
Customer Retention
Product Led Growth
Product Led Growth
In-App Support
In-App Support
Roles
Roles
Product Growth
Product Growth
Product Marketing
Product Marketing
Product Management
Product Management
UX Design
UX Design
Resources
Resources
Blog
Blog
Product Adoption School
Product Adoption School
Product Drive
Product Drive
SaaS Onboarding Research
SaaS Onboarding Research
Case Studies
Case Studies
Sitemap
Sitemap
Support
Support
Help Center
Help Center
System Status
System Status
Trust Center
Trust Center
Read more
Read more
User Onboarding
User Onboarding
Product Tours
Product Tours
Customer Success
Customer Success
User Behavior Tracking
User Behavior Tracking
In-App Guidance
In-App Guidance
Microsurveys for SaaS Guide
Microsurveys for SaaS Guide
Interactive User Guides
Interactive User Guides
© 2026 Userpilot. All rights reserved
Terms of Use
Terms of Use...
|
NULL
|
|
8544
|
165
|
12
|
2026-04-14T06:51:22.047656+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776149482047_m2.jpg...
|
Firefox
|
Jy 19798 evaluation for ai activity types by nikol Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet — Work...
|
1
|
github.com/jiminny/prophet/pull/468/changes#diff-d github.com/jiminny/prophet/pull/468/changes#diff-d2f9fea9bc428b119ae26a66453e8eab7dd0782d4a4d93075ca5ce05903d77e8...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
You said
I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.
Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
Expand
Listen
Show more options
Gemini said
Gemini said
This Python script defines the
AiActivityTypeEvaluator
class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.
Core Functionality
Core Functionality
Data Collection (
collect_test_set
):
* Supports fetching raw samples from
Elasticsearch (ES)
or loading them from
local JSON files
.
Implements a
replayability check
: It probes the live API endpoint to ensure the activity exists before including it in the dataset.
Filters data based on request body size, language, and the presence of an original response.
Ground Truth Management:
Saves inputs and "gold standard" responses to a local directory structure (
eval_output/ai_activity_type/...
).
Features an optional mode to populate ground truth using a high-order LLM (e.g.,
gpt-5_2
) if the
POPULATE_GROUND_TRUTH_LLM
flag is set.
Evaluation Logic (
evaluate_against_ground_truth
):
Compares the model's predicted
ai_activity_type
against either the original ES response or the LLM-generated ground truth.
Assigns a
quality_score
of
1.0
for a match and
0.0
for a mismatch or request failure.
Key Configuration Constants
Key Configuration Constants
Constant
Purpose
ENDPOINT_PATH
The specific API route being tested:
call/ai-activity-type
.
COMPARE_TO_GROUND_TRUTH
Determines if the baseline is the original data (
es
) or an
llm
.
SKIP_UNREPLAYABLE_ON_COLLECT
If
True
, discards records where the API returns "Cannot find activity."
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Limits the probe request to 20 seconds.
Constant
ENDPOINT_PATH
COMPARE_TO_GROUND_TRUTH
SKIP_UNREPLAYABLE_ON_COLLECT
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Purpose
The specific API route being tested:
call/ai-activity-type
.
Determines if the baseline is the original data (
es
) or an
llm
.
If
True
, discards records where the API returns "Cannot find activity."
Limits the probe request to 20 seconds.
Copy table
Execution Workflow
Execution Workflow
Parsing:
The script uses
create_parser
to handle CLI arguments like
--data-set
,
--populate-ground-truth-llm
, and
--compare-to-ground-truth
.
Initialization:
Sets up directory paths for inputs and ground truths based on the selected dataset name.
Run:
Executes the evaluation via
asyncio.run(run_evaluation(...))
, which orchestrates the collection, endpoint calling, and result scoring phases.
Copy prompt
Edit
You said are there soem issues with this PR
You said
are there soem issues with this PR
Show more options
Show thinking
Gemini said
Gemini said
Yes,
there are several issues and code smells in this Pull Request,
ranging from performance bottlenecks to architectural anti-patterns.
Here is a breakdown of the most notable issues,
categorized by impact:
Performance & Async Anti-Patterns
Performance & Async Anti-Patterns
Sequential Requests Defeating Async (Lines 86-106):
Inside
_collect_from_es
,
the code loops through
raw_samples
and
await
s a
session.post
request for each sample one by one.
This means the script waits for one HTTP request to finish before starting the next,
completely defeating the purpose of using
aiohttp
for asynchronous concurrency.
Fix:
Collect these coroutines into a list and use
asyncio.gather()
(ideally wrapped in an
asyncio.Semaphore
to avoid overwhelming the endpoint) to run the replayability probes concurrently.
Blocking File I/O in Async Functions (Lines 110-114, 184-188, 268-269):
Standard synchronous file operations (
with open(...)
,
json.dump
,
json.load
) are used inside
async def
functions.
In Python,
this blocks the entire event loop while the disk is reading/writing.
Fix:
Use an asynchronous file I/O library like
aiofiles
,
or run the blocking I/O operations in a separate thread using
asyncio.to_thread()...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.11736111,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.14097223,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\\nExpected: {gt_label}\\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\\nExpected: {gt_label}\\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Listen","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This Python script defines the","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AiActivityTypeEvaluator","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Core Functionality","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Core Functionality","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Data Collection (","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"collect_test_set","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"* Supports fetching raw samples from","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Elasticsearch (ES)","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or loading them from","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"local JSON files","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Implements a","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"replayability check","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":": It probes the live API endpoint to ensure the activity exists before including it in the dataset.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filters data based on request body size, language, and the presence of an original response.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ground Truth Management:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saves inputs and \"gold standard\" responses to a local directory structure (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"eval_output/ai_activity_type/...","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":").","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Features an optional mode to populate ground truth using a high-order LLM (e.g.,","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"gpt-5_2","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") if the","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POPULATE_GROUND_TRUTH_LLM","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"flag is set.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Evaluation Logic (","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"evaluate_against_ground_truth","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Compares the model's predicted","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ai_activity_type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"against either the original ES response or the LLM-generated ground truth.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Assigns a","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"quality_score","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"of","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.0","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for a match and","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.0","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for a mismatch or request failure.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Key Configuration Constants","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Key Configuration Constants","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Constant","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Purpose","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ENDPOINT_PATH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The specific API route being tested:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"call/ai-activity-type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"COMPARE_TO_GROUND_TRUTH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Determines if the baseline is the original data (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"es","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") or an","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"llm","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SKIP_UNREPLAYABLE_ON_COLLECT","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"True","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", discards records where the API returns \"Cannot find activity.\"","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"REPLAYABILITY_CHECK_TIMEOUT_SECONDS","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Limits the probe request to 20 seconds.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Constant","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ENDPOINT_PATH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"COMPARE_TO_GROUND_TRUTH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SKIP_UNREPLAYABLE_ON_COLLECT","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"REPLAYABILITY_CHECK_TIMEOUT_SECONDS","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Purpose","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The specific API route being tested:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"call/ai-activity-type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Determines if the baseline is the original data (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"es","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") or an","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"llm","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"True","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", discards records where the API returns \"Cannot find activity.\"","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Limits the probe request to 20 seconds.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy table","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Execution Workflow","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Execution Workflow","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Parsing:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The script uses","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"create_parser","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to handle CLI arguments like","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--data-set","depth":27,"bounds":{"left":0.1171875,"top":0.0,"width":0.107421875,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"bounds":{"left":0.12929687,"top":0.0,"width":0.003125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--populate-ground-truth-llm","depth":27,"bounds":{"left":0.13476562,"top":0.0,"width":0.08867188,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", and","depth":26,"bounds":{"left":0.1171875,"top":0.0,"width":0.11171875,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--compare-to-ground-truth","depth":27,"bounds":{"left":0.13203125,"top":0.0,"width":0.08203125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"bounds":{"left":0.21640626,"top":0.0,"width":0.0015625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Initialization:","depth":26,"bounds":{"left":0.1171875,"top":0.0,"width":0.039453126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sets up directory paths for inputs and ground truths based on the selected dataset name.","depth":26,"bounds":{"left":0.1171875,"top":0.0,"width":0.11875,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Run:","depth":26,"bounds":{"left":0.1171875,"top":0.024305556,"width":0.013671875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Executes the evaluation via","depth":26,"bounds":{"left":0.13085938,"top":0.024305556,"width":0.080078125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"asyncio.run(run_evaluation(...))","depth":27,"bounds":{"left":0.11953125,"top":0.04375,"width":0.10507812,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", which orchestrates the collection, endpoint calling, and result scoring phases.","depth":26,"bounds":{"left":0.1171875,"top":0.04236111,"width":0.11289062,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said are there soem issues with this PR","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.03888889},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"are there soem issues with this PR","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.062109374,"height":0.034027778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.22986111,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.23680556,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.27291667,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.27430555,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Yes,","depth":24,"bounds":{"left":0.10390625,"top":0.28125,"width":0.011328125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"there are several issues and code smells in this Pull Request,","depth":24,"bounds":{"left":0.10390625,"top":0.28125,"width":0.12890625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ranging from performance bottlenecks to architectural anti-patterns.","depth":24,"bounds":{"left":0.10390625,"top":0.29930556,"width":0.13242188,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Here is a breakdown of the most notable issues,","depth":24,"bounds":{"left":0.10390625,"top":0.34652779,"width":0.11640625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"categorized by impact:","depth":24,"bounds":{"left":0.123046875,"top":0.36458334,"width":0.06679688,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Performance & Async Anti-Patterns","depth":23,"bounds":{"left":0.10390625,"top":0.4,"width":0.13242188,"height":0.016666668},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Performance & Async Anti-Patterns","depth":24,"bounds":{"left":0.10390625,"top":0.40138888,"width":0.10859375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sequential Requests Defeating Async (Lines 86-106):","depth":26,"bounds":{"left":0.11757813,"top":0.42430556,"width":0.11601563,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Inside","depth":26,"bounds":{"left":0.16289063,"top":0.44236112,"width":0.019921875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"_collect_from_es","depth":27,"bounds":{"left":0.11992188,"top":0.46180555,"width":0.05234375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"bounds":{"left":0.17460938,"top":0.46041667,"width":0.001953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"the code loops through","depth":26,"bounds":{"left":0.11757813,"top":0.46041667,"width":0.10429688,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"raw_samples","depth":27,"bounds":{"left":0.14414063,"top":0.4798611,"width":0.0359375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":26,"bounds":{"left":0.18242188,"top":0.47847223,"width":0.0140625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"await","depth":27,"bounds":{"left":0.19882813,"top":0.4798611,"width":0.01640625,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s a","depth":26,"bounds":{"left":0.21757813,"top":0.47847223,"width":0.009765625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"session.post","depth":27,"bounds":{"left":0.11992188,"top":0.49791667,"width":0.039453126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"request for each sample one by one.","depth":26,"bounds":{"left":0.11757813,"top":0.4965278,"width":0.11640625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This means the script waits for one HTTP request to finish before starting the next,","depth":26,"bounds":{"left":0.11757813,"top":0.51458335,"width":0.11289062,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"completely defeating the purpose of using","depth":26,"bounds":{"left":0.11757813,"top":0.55069447,"width":0.11171875,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"aiohttp","depth":27,"bounds":{"left":0.18046875,"top":0.5701389,"width":0.023046875,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for asynchronous concurrency.","depth":26,"bounds":{"left":0.11757813,"top":0.56875,"width":0.09921875,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fix:","depth":28,"bounds":{"left":0.1296875,"top":0.61041665,"width":0.009765625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Collect these coroutines into a list and use","depth":28,"bounds":{"left":0.1296875,"top":0.61041665,"width":0.09921875,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"asyncio.gather()","depth":29,"bounds":{"left":0.16601562,"top":0.6298611,"width":0.05234375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(ideally wrapped in an","depth":28,"bounds":{"left":0.1296875,"top":0.6284722,"width":0.09257813,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"asyncio.Semaphore","depth":29,"bounds":{"left":0.13203125,"top":0.66597223,"width":0.055859376,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to avoid overwhelming the endpoint) to run the replayability probes concurrently.","depth":28,"bounds":{"left":0.1296875,"top":0.6645833,"width":0.10546875,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Blocking File I/O in Async Functions (Lines 110-114, 184-188, 268-269):","depth":26,"bounds":{"left":0.11757813,"top":0.72430557,"width":0.10976563,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Standard synchronous file operations (","depth":26,"bounds":{"left":0.11757813,"top":0.7423611,"width":0.107421875,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"with open(...)","depth":27,"bounds":{"left":0.12226562,"top":0.7798611,"width":0.045703124,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"bounds":{"left":0.1703125,"top":0.77847224,"width":0.0015625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json.dump","depth":27,"bounds":{"left":0.17617187,"top":0.7798611,"width":0.029296875,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"bounds":{"left":0.2078125,"top":0.77847224,"width":0.0015625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json.load","depth":27,"bounds":{"left":0.11992188,"top":0.79791665,"width":0.0296875,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") are used inside","depth":26,"bounds":{"left":0.15195313,"top":0.7965278,"width":0.048046876,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"async def","depth":27,"bounds":{"left":0.20234375,"top":0.79791665,"width":0.0296875,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"functions.","depth":26,"bounds":{"left":0.11757813,"top":0.7965278,"width":0.11796875,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"In Python,","depth":26,"bounds":{"left":0.14570312,"top":0.81458336,"width":0.030078124,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"this blocks the entire event loop while the disk is reading/writing.","depth":26,"bounds":{"left":0.11757813,"top":0.81458336,"width":0.11875,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fix:","depth":28,"bounds":{"left":0.1296875,"top":0.87430555,"width":0.009765625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use an asynchronous file I/O library like","depth":28,"bounds":{"left":0.1296875,"top":0.87430555,"width":0.09335937,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"aiofiles","depth":29,"bounds":{"left":0.1625,"top":0.89375,"width":0.0265625,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":28,"bounds":{"left":0.19140625,"top":0.8923611,"width":0.0015625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or run the blocking I/O operations in a separate thread using","depth":28,"bounds":{"left":0.1296875,"top":0.8923611,"width":0.10585938,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"asyncio.to_thread()","depth":29,"bounds":{"left":0.16914062,"top":0.9298611,"width":0.0625,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
2043951250885907759
|
9020551951192732151
|
visual_change
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
You said
I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.
Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
Expand
Listen
Show more options
Gemini said
Gemini said
This Python script defines the
AiActivityTypeEvaluator
class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.
Core Functionality
Core Functionality
Data Collection (
collect_test_set
):
* Supports fetching raw samples from
Elasticsearch (ES)
or loading them from
local JSON files
.
Implements a
replayability check
: It probes the live API endpoint to ensure the activity exists before including it in the dataset.
Filters data based on request body size, language, and the presence of an original response.
Ground Truth Management:
Saves inputs and "gold standard" responses to a local directory structure (
eval_output/ai_activity_type/...
).
Features an optional mode to populate ground truth using a high-order LLM (e.g.,
gpt-5_2
) if the
POPULATE_GROUND_TRUTH_LLM
flag is set.
Evaluation Logic (
evaluate_against_ground_truth
):
Compares the model's predicted
ai_activity_type
against either the original ES response or the LLM-generated ground truth.
Assigns a
quality_score
of
1.0
for a match and
0.0
for a mismatch or request failure.
Key Configuration Constants
Key Configuration Constants
Constant
Purpose
ENDPOINT_PATH
The specific API route being tested:
call/ai-activity-type
.
COMPARE_TO_GROUND_TRUTH
Determines if the baseline is the original data (
es
) or an
llm
.
SKIP_UNREPLAYABLE_ON_COLLECT
If
True
, discards records where the API returns "Cannot find activity."
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Limits the probe request to 20 seconds.
Constant
ENDPOINT_PATH
COMPARE_TO_GROUND_TRUTH
SKIP_UNREPLAYABLE_ON_COLLECT
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Purpose
The specific API route being tested:
call/ai-activity-type
.
Determines if the baseline is the original data (
es
) or an
llm
.
If
True
, discards records where the API returns "Cannot find activity."
Limits the probe request to 20 seconds.
Copy table
Execution Workflow
Execution Workflow
Parsing:
The script uses
create_parser
to handle CLI arguments like
--data-set
,
--populate-ground-truth-llm
, and
--compare-to-ground-truth
.
Initialization:
Sets up directory paths for inputs and ground truths based on the selected dataset name.
Run:
Executes the evaluation via
asyncio.run(run_evaluation(...))
, which orchestrates the collection, endpoint calling, and result scoring phases.
Copy prompt
Edit
You said are there soem issues with this PR
You said
are there soem issues with this PR
Show more options
Show thinking
Gemini said
Gemini said
Yes,
there are several issues and code smells in this Pull Request,
ranging from performance bottlenecks to architectural anti-patterns.
Here is a breakdown of the most notable issues,
categorized by impact:
Performance & Async Anti-Patterns
Performance & Async Anti-Patterns
Sequential Requests Defeating Async (Lines 86-106):
Inside
_collect_from_es
,
the code loops through
raw_samples
and
await
s a
session.post
request for each sample one by one.
This means the script waits for one HTTP request to finish before starting the next,
completely defeating the purpose of using
aiohttp
for asynchronous concurrency.
Fix:
Collect these coroutines into a list and use
asyncio.gather()
(ideally wrapped in an
asyncio.Semaphore
to avoid overwhelming the endpoint) to run the replayability probes concurrently.
Blocking File I/O in Async Functions (Lines 110-114, 184-188, 268-269):
Standard synchronous file operations (
with open(...)
,
json.dump
,
json.load
) are used inside
async def
functions.
In Python,
this blocks the entire event loop while the disk is reading/writing.
Fix:
Use an asynchronous file I/O library like
aiofiles
,
or run the blocking I/O operations in a separate thread using
asyncio.to_thread()...
|
NULL
|
|
10045
|
195
|
23
|
2026-04-14T08:09:35.600551+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154175600_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/mie-gawc-dsi
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Return to home screen
[EMAIL]
Switch account
Switch account
Lukas Kovalik
More options
Turn off microphone
Turn off camera
Turn on background blur
Microphone: soundcore AeroClip
Speaker: System Default Speaker Device
Camera: FaceTime HD Camera
Backgrounds and effects
Enhance your appearance
Enhance your appearance
Meet can adjust your image sharpness and lighting so others can see you better. To change how you look, use the Appearance tab.
Not now
Try now
Try now
Daily - Platform
Daily - Platform
Scheduled for
Thu, Apr 16
9:45 AM
Use Gemini to take notes Share notes and transcript
Use Gemini to take notes
Share notes and transcript
Start
Start
Join anyway
Join anyway
Other ways to join
Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.
Learn more
Learn more...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"bounds":{"left":0.015625,"top":0.4625,"width":0.046484374,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.016796876,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.51111114,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"bounds":{"left":0.109375,"top":0.8020833,"width":0.125,"height":0.05},"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"bounds":{"left":0.109375,"top":0.8034722,"width":0.10625,"height":0.047916666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Return to home screen","depth":10,"bounds":{"left":0.259375,"top":0.05625,"width":0.041015625,"height":0.027777778},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.9097656,"top":0.057638887,"width":0.06523438,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Switch account","depth":11,"bounds":{"left":0.94023436,"top":0.06875,"width":0.034765624,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch account","depth":12,"bounds":{"left":0.94023436,"top":0.06875,"width":0.034765624,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":14,"bounds":{"left":0.39765626,"top":0.36319444,"width":0.03515625,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More options","depth":13,"bounds":{"left":0.6578125,"top":0.35277778,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":14,"bounds":{"left":0.496875,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Turn off camera","depth":14,"bounds":{"left":0.525,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Turn on background blur","depth":13,"bounds":{"left":0.553125,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Microphone: soundcore AeroClip","depth":12,"bounds":{"left":0.39140624,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Speaker: System Default Speaker Device","depth":13,"bounds":{"left":0.46445313,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Camera: FaceTime HD Camera","depth":13,"bounds":{"left":0.5375,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Backgrounds and effects","depth":12,"bounds":{"left":0.6105469,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Enhance your appearance","depth":14,"bounds":{"left":0.5679687,"top":0.5138889,"width":0.07539062,"height":0.016666668},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Enhance your appearance","depth":15,"bounds":{"left":0.5679687,"top":0.51458335,"width":0.07539062,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Meet can adjust your image sharpness and lighting so others can see you better. To change how you look, use the Appearance tab.","depth":15,"bounds":{"left":0.55546874,"top":0.53333336,"width":0.10507812,"height":0.05486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Not now","depth":15,"bounds":{"left":0.590625,"top":0.6,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Try now","depth":15,"bounds":{"left":0.62578124,"top":0.6,"width":0.0390625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Try now","depth":17,"bounds":{"left":0.6351563,"top":0.60694444,"width":0.0203125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":11,"bounds":{"left":0.68671876,"top":0.3888889,"width":0.175,"height":0.025},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":14,"bounds":{"left":0.7363281,"top":0.38819444,"width":0.07578125,"height":0.025694445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Scheduled for","depth":12,"bounds":{"left":0.7601563,"top":0.425,"width":0.035546876,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Thu, Apr 16","depth":12,"bounds":{"left":0.73164064,"top":0.43888888,"width":0.046484374,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9:45 AM","depth":12,"bounds":{"left":0.7828125,"top":0.43888888,"width":0.033984374,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use Gemini to take notes Share notes and transcript","depth":11,"bounds":{"left":0.71132815,"top":0.4722222,"width":0.12578125,"height":0.044444446},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Use Gemini to take notes","depth":12,"bounds":{"left":0.73476565,"top":0.48194444,"width":0.06328125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Share notes and transcript","depth":12,"bounds":{"left":0.73476565,"top":0.49583334,"width":0.056640625,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start","depth":12,"bounds":{"left":0.8011719,"top":0.48055556,"width":0.03125,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start","depth":14,"bounds":{"left":0.8105469,"top":0.4875,"width":0.0125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Join anyway","depth":12,"bounds":{"left":0.72734374,"top":0.5277778,"width":0.09375,"height":0.03888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join anyway","depth":14,"bounds":{"left":0.75859374,"top":0.5402778,"width":0.03125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Other ways to join","depth":12,"bounds":{"left":0.7378906,"top":0.5861111,"width":0.07265625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.","depth":12,"bounds":{"left":0.50273436,"top":0.9375,"width":0.26328126,"height":0.035416666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more","depth":12,"bounds":{"left":0.64453125,"top":0.9611111,"width":0.027734375,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":13,"bounds":{"left":0.64453125,"top":0.9611111,"width":0.027734375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-3182521423525855285
|
9019892165224168526
|
click
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Return to home screen
[EMAIL]
Switch account
Switch account
Lukas Kovalik
More options
Turn off microphone
Turn off camera
Turn on background blur
Microphone: soundcore AeroClip
Speaker: System Default Speaker Device
Camera: FaceTime HD Camera
Backgrounds and effects
Enhance your appearance
Enhance your appearance
Meet can adjust your image sharpness and lighting so others can see you better. To change how you look, use the Appearance tab.
Not now
Try now
Try now
Daily - Platform
Daily - Platform
Scheduled for
Thu, Apr 16
9:45 AM
Use Gemini to take notes Share notes and transcript
Use Gemini to take notes
Share notes and transcript
Start
Start
Join anyway
Join anyway
Other ways to join
Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.
Learn more
Learn more...
|
10044
|
|
10051
|
195
|
26
|
2026-04-14T08:09:44.783540+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154184783_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/mie-gawc-dsi
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Return to home screen
[EMAIL]
Switch account
Switch account
Lukas Kovalik
More options
Turn off microphone
Turn off camera
Turn on background blur
Microphone: soundcore AeroClip
Speaker: System Default Speaker Device
Camera: FaceTime HD Camera
Backgrounds and effects
Enhance your appearance
Enhance your appearance
Meet can adjust your image sharpness and lighting so others can see you better. To change how you look, use the Appearance tab.
Not now
Try now
Try now
Daily - Platform
Daily - Platform
Scheduled for
Thu, Apr 16
9:45 AM
Use Gemini to take notes Share notes and transcript
Use Gemini to take notes
Share notes and transcript
Start
Start
Join anyway
Join anyway
Other ways to join
Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.
Learn more
Learn more...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"bounds":{"left":0.015625,"top":0.4625,"width":0.046484374,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.016796876,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.51111114,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"bounds":{"left":0.109375,"top":0.8020833,"width":0.125,"height":0.05},"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"bounds":{"left":0.109375,"top":0.8034722,"width":0.10625,"height":0.047916666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Return to home screen","depth":10,"bounds":{"left":0.259375,"top":0.05625,"width":0.041015625,"height":0.027777778},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.9097656,"top":0.057638887,"width":0.06523438,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Switch account","depth":11,"bounds":{"left":0.94023436,"top":0.06875,"width":0.034765624,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch account","depth":12,"bounds":{"left":0.94023436,"top":0.06875,"width":0.034765624,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":14,"bounds":{"left":0.39765626,"top":0.36319444,"width":0.03515625,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More options","depth":13,"bounds":{"left":0.6578125,"top":0.35277778,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":14,"bounds":{"left":0.496875,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Turn off camera","depth":14,"bounds":{"left":0.525,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Turn on background blur","depth":13,"bounds":{"left":0.553125,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Microphone: soundcore AeroClip","depth":12,"bounds":{"left":0.39140624,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Speaker: System Default Speaker Device","depth":13,"bounds":{"left":0.46445313,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Camera: FaceTime HD Camera","depth":13,"bounds":{"left":0.5375,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Backgrounds and effects","depth":12,"bounds":{"left":0.6105469,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Enhance your appearance","depth":14,"bounds":{"left":0.5679687,"top":0.5138889,"width":0.07539062,"height":0.016666668},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Enhance your appearance","depth":15,"bounds":{"left":0.5679687,"top":0.51458335,"width":0.07539062,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Meet can adjust your image sharpness and lighting so others can see you better. To change how you look, use the Appearance tab.","depth":15,"bounds":{"left":0.55546874,"top":0.53333336,"width":0.10507812,"height":0.05486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Not now","depth":15,"bounds":{"left":0.590625,"top":0.6,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Try now","depth":15,"bounds":{"left":0.62578124,"top":0.6,"width":0.0390625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Try now","depth":17,"bounds":{"left":0.6351563,"top":0.60694444,"width":0.0203125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":11,"bounds":{"left":0.68671876,"top":0.3888889,"width":0.175,"height":0.025},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":14,"bounds":{"left":0.7363281,"top":0.38819444,"width":0.07578125,"height":0.025694445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Scheduled for","depth":12,"bounds":{"left":0.7601563,"top":0.425,"width":0.035546876,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Thu, Apr 16","depth":12,"bounds":{"left":0.73164064,"top":0.43888888,"width":0.046484374,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9:45 AM","depth":12,"bounds":{"left":0.7828125,"top":0.43888888,"width":0.033984374,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use Gemini to take notes Share notes and transcript","depth":11,"bounds":{"left":0.71132815,"top":0.4722222,"width":0.12578125,"height":0.044444446},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Use Gemini to take notes","depth":12,"bounds":{"left":0.73476565,"top":0.48194444,"width":0.06328125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Share notes and transcript","depth":12,"bounds":{"left":0.73476565,"top":0.49583334,"width":0.056640625,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start","depth":12,"bounds":{"left":0.8011719,"top":0.48055556,"width":0.03125,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start","depth":14,"bounds":{"left":0.8105469,"top":0.4875,"width":0.0125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Join anyway","depth":12,"bounds":{"left":0.72734374,"top":0.5277778,"width":0.09375,"height":0.03888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join anyway","depth":14,"bounds":{"left":0.75859374,"top":0.5402778,"width":0.03125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Other ways to join","depth":12,"bounds":{"left":0.7378906,"top":0.5861111,"width":0.07265625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.","depth":12,"bounds":{"left":0.50273436,"top":0.9375,"width":0.26328126,"height":0.035416666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more","depth":12,"bounds":{"left":0.64453125,"top":0.9611111,"width":0.027734375,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":13,"bounds":{"left":0.64453125,"top":0.9611111,"width":0.027734375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-3182521423525855285
|
9019892165224168526
|
click
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Return to home screen
[EMAIL]
Switch account
Switch account
Lukas Kovalik
More options
Turn off microphone
Turn off camera
Turn on background blur
Microphone: soundcore AeroClip
Speaker: System Default Speaker Device
Camera: FaceTime HD Camera
Backgrounds and effects
Enhance your appearance
Enhance your appearance
Meet can adjust your image sharpness and lighting so others can see you better. To change how you look, use the Appearance tab.
Not now
Try now
Try now
Daily - Platform
Daily - Platform
Scheduled for
Thu, Apr 16
9:45 AM
Use Gemini to take notes Share notes and transcript
Use Gemini to take notes
Share notes and transcript
Start
Start
Join anyway
Join anyway
Other ways to join
Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.
Learn more
Learn more...
|
NULL
|
|
10057
|
195
|
30
|
2026-04-14T08:09:53.446200+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154193446_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/mie-gawc-dsi
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Mute tab
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Return to home screen
[EMAIL]
Switch account
Switch account
Lukas Kovalik
More options
Turn off microphone
Turn off camera
Turn on background blur
Microphone: soundcore AeroClip
Speaker: System Default Speaker Device
Camera: FaceTime HD Camera
Backgrounds and effects
Daily - Platform
Daily - Platform
Scheduled for
Thu, Apr 16
9:45 AM
Use Gemini to take notes Share notes and transcript
Use Gemini to take notes
Share notes and transcript
Start
Start
Join anyway
Join anyway
Other ways to join
Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.
Learn more
Learn more...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Mute tab","depth":5,"bounds":{"left":0.01328125,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"bounds":{"left":0.0234375,"top":0.4625,"width":0.046875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.016796876,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.51111114,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"bounds":{"left":0.109375,"top":0.8020833,"width":0.125,"height":0.05},"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"bounds":{"left":0.109375,"top":0.8034722,"width":0.10625,"height":0.047916666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Return to home screen","depth":10,"bounds":{"left":0.259375,"top":0.05625,"width":0.041015625,"height":0.027777778},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.9097656,"top":0.057638887,"width":0.06523438,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Switch account","depth":11,"bounds":{"left":0.94023436,"top":0.06875,"width":0.034765624,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch account","depth":12,"bounds":{"left":0.94023436,"top":0.06875,"width":0.034765624,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":14,"bounds":{"left":0.39765626,"top":0.36319444,"width":0.03515625,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More options","depth":13,"bounds":{"left":0.6578125,"top":0.35277778,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":14,"bounds":{"left":0.496875,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Turn off camera","depth":14,"bounds":{"left":0.525,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Turn on background blur","depth":13,"bounds":{"left":0.553125,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Microphone: soundcore AeroClip","depth":12,"bounds":{"left":0.39140624,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Speaker: System Default Speaker Device","depth":13,"bounds":{"left":0.46445313,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Camera: FaceTime HD Camera","depth":13,"bounds":{"left":0.5375,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Backgrounds and effects","depth":13,"bounds":{"left":0.6105469,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":true},{"role":"AXHeading","text":"Daily - Platform","depth":11,"bounds":{"left":0.68671876,"top":0.3888889,"width":0.175,"height":0.025},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":14,"bounds":{"left":0.7363281,"top":0.38819444,"width":0.07578125,"height":0.025694445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Scheduled for","depth":12,"bounds":{"left":0.7601563,"top":0.425,"width":0.035546876,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Thu, Apr 16","depth":12,"bounds":{"left":0.73164064,"top":0.43888888,"width":0.046484374,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9:45 AM","depth":12,"bounds":{"left":0.7828125,"top":0.43888888,"width":0.033984374,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use Gemini to take notes Share notes and transcript","depth":11,"bounds":{"left":0.71132815,"top":0.4722222,"width":0.12578125,"height":0.044444446},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Use Gemini to take notes","depth":12,"bounds":{"left":0.73476565,"top":0.48194444,"width":0.06328125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Share notes and transcript","depth":12,"bounds":{"left":0.73476565,"top":0.49583334,"width":0.056640625,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start","depth":12,"bounds":{"left":0.8011719,"top":0.48055556,"width":0.03125,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start","depth":14,"bounds":{"left":0.8105469,"top":0.4875,"width":0.0125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Join anyway","depth":12,"bounds":{"left":0.72734374,"top":0.5277778,"width":0.09375,"height":0.03888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join anyway","depth":14,"bounds":{"left":0.75859374,"top":0.5402778,"width":0.03125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Other ways to join","depth":12,"bounds":{"left":0.7378906,"top":0.5861111,"width":0.07265625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.","depth":12,"bounds":{"left":0.50273436,"top":0.9375,"width":0.26328126,"height":0.035416666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more","depth":12,"bounds":{"left":0.64453125,"top":0.9611111,"width":0.027734375,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":13,"bounds":{"left":0.64453125,"top":0.9611111,"width":0.027734375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
4831100491306820337
|
9019883369122758222
|
click
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Mute tab
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Return to home screen
[EMAIL]
Switch account
Switch account
Lukas Kovalik
More options
Turn off microphone
Turn off camera
Turn on background blur
Microphone: soundcore AeroClip
Speaker: System Default Speaker Device
Camera: FaceTime HD Camera
Backgrounds and effects
Daily - Platform
Daily - Platform
Scheduled for
Thu, Apr 16
9:45 AM
Use Gemini to take notes Share notes and transcript
Use Gemini to take notes
Share notes and transcript
Start
Start
Join anyway
Join anyway
Other ways to join
Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.
Learn more
Learn more...
|
NULL
|
|
53478
|
1156
|
25
|
2026-04-20T08:14:23.968980+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-20/1776 /Users/lukas/.screenpipe/data/data/2026-04-20/1776672863968_m1.jpg...
|
PhpStorm
|
Code Analysis
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Code Analysis
text/html
text/html
text/html
File ~ Code Analysis
text/html
text/html
text/html
File ~/jiminny/app/app/Listeners/AutomatedReports/UserPilot/TrackAutomatedReportGeneratedEvent.php contains problems.<br/>No errors and one warning found.<br/>Would you like to review them?...
|
[{"role":"AXTextField","text [{"role":"AXTextField","text":"Code Analysis","depth":1,"value":"Code Analysis","help_text":"text/html","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"text/html","depth":2,"help_text":"text/html","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"text/html","depth":2,"help_text":"text/html","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"text/html","depth":2,"help_text":"text/html","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"File ~/jiminny/app/app/Listeners/AutomatedReports/UserPilot/TrackAutomatedReportGeneratedEvent.php contains problems.<br/>No errors and one warning found.<br/>Would you like to review them?","depth":1,"help_text":"text/html","role_description":"text"}]...
|
5710727982699704906
|
9012223542781775567
|
click
|
accessibility
|
NULL
|
Code Analysis
text/html
text/html
text/html
File ~ Code Analysis
text/html
text/html
text/html
File ~/jiminny/app/app/Listeners/AutomatedReports/UserPilot/TrackAutomatedReportGeneratedEvent.php contains problems.<br/>No errors and one warning found.<br/>Would you like to review them?...
|
53475
|
|
19304
|
411
|
7
|
2026-04-15T07:30:38.783953+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-15/1776 /Users/lukas/.screenpipe/data/data/2026-04-15/1776238238783_m1.jpg...
|
Firefox
|
Product Growth Platform | Userpilot — Work
|
1
|
userpilot.com
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Team - Backlog - Jira
Service-Desk - Queu Platform Team - Backlog - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Inbox (1,550) - [EMAIL] - Jiminny Mail
For you - Confluence
For you - Confluence
Lukas Kovalik - Time Off
Lukas Kovalik - Time Off
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Userpilot
Platform
Platform
Solutions
Solutions
Pricing
Pricing
Integrations
Integrations
Resources
Resources
Customers
Customers
Free Trial
Free Trial
Log in
Log in
Get a Demo
Get a Demo
Drive Product Growth with
Drive Product Growth with
User Insights.
User Engagement.
User Feedback.
Leverage user insights & in-app engagement to drive adoption, retention, and revenue.
Enter your email address
Get a Demo
coming soon Userpilot AI
coming soon
Userpilot AI
In-app Engagement
In-app Engagement
Product Analytics
Product Analytics
User Feedback
User Feedback
Session Replay
Session Replay
Join 1,000+ Companies Accelerating Product Growth With Userpilot.
Introducing Lia
Userpilot’s AI Agent for Product Growth
Userpilot’s AI Agent for Product Growth
Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.
Learn more about Lia
Learn more about Lia
User Onboarding
User Onboarding
Guide new users through your product and reduce time-to-value.
Help existing users discover new features contextually.
See User Onboarding Solutions
See User Onboarding Solutions
Product Analytics
Product Analytics
Understand user behavior across the product journey.
Generate custom reports to answer any product question.
See Analytics Features
See Analytics Features
User Feedback
User Feedback
Capture and analyze user sentiment at scale.
Understand how your users really feel with contextual Microsurveys.
See User Feedback Tools
See User Feedback Tools
Session Replay
Session Replay
Learn how users interact with your product.
Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.
See Session Replay Features
See Session Replay Features
Userpilot for Mobile
Userpilot for Mobile
Use mobile-first UI patterns.
Onboard users, run surveys, and track product metrics on native mobile devices.
Explore Mobile Features
Explore Mobile Features
Rally Your Whole Team Around Your Product Growth Goals.
Rally Your Whole Team Around Your Product Growth Goals.
Start 14 Days Free Trial
Start 14 Days Free Trial
No credit card required
Kontentino improved New User Activation Rate by 10% in 1 month
Kontentino improved New User Activation Rate by 10% in 1 month
“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”
Integrate Userpilot with your favorite tech stack
Integrate Userpilot with your favorite tech stack
Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.
Learn More
Learn More
Unlock the Power of Product-Led Growth
Unlock the Power of Product-Led Growth
Best practices to help you
activate more users, increase user engagement
and
drive more product growth.
Userpilot Blog Learn about product growth, good UX and the latest trends in product management.
Userpilot Blog
Userpilot Blog
Learn about product growth, good UX and the latest trends in product management.
Read
Read
Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.
Upcoming Webinars
Upcoming Webinars
Upcoming live webinars, on-demand videos and webcasts.
Watch
Watch
Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Product Drive Conference
Product Drive Conference
Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Connect
Connect
Take Your Product Experience to the Next Level
Get a Demo
Get a Demo
Product
Product
Product Analytics
Product Analytics
User Engagement
User Engagement
User Feedback
User Feedback
Company
Company
Events
Events
Careers
Careers
Customers
Customers
Contact Us
Contact Us
About Us
About Us
Use Cases
Use Cases
User Onboarding
User Onboarding
Product Adoption
Product Adoption
Customer Retention
Customer Retention
Product Led Growth
Product Led Growth
In-App Support
In-App Support
Roles
Roles
Product Growth
Product Growth
Product Marketing
Product Marketing
Product Management
Product Management
UX Design
UX Design
Resources
Resources
Blog
Blog
Product Adoption School
Product Adoption School
Product Drive
Product Drive
SaaS Onboarding Research
SaaS Onboarding Research
Case Studies
Case Studies
Sitemap
Sitemap
Support
Support
Help Center
Help Center
System Status
System Status
Trust Center
Trust Center
Read more
Read more
User Onboarding
User Onboarding
Product Tours
Product Tours
Customer Success
Customer Success
User Behavior Tracking
User Behavior Tracking
In-App Guidance
In-App Guidance
Microsurveys for SaaS Guide
Microsurveys for SaaS Guide
Interactive User Guides
Interactive User Guides
© 2026 Userpilot. All rights reserved
Terms of Use
Terms of Use
Privacy Policy
Privacy Policy
Your consent preferences for tracking technologies
Your consent preferences for tracking technologies
Open live chat...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Team - Backlog - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox (1,550) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"For you - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Lukas Kovalik - Time Off","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lukas Kovalik - Time Off","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Product Growth Platform | Userpilot","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Product Growth Platform | Userpilot","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Userpilot","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Platform","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Solutions","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Solutions","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pricing","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pricing","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Integrations","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Integrations","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Resources","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Resources","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customers","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customers","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Free Trial","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Free Trial","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Log in","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Log in","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Get a Demo","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Get a Demo","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Drive Product Growth with","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Drive Product Growth with","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Insights.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Engagement.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Feedback.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Leverage user insights & in-app engagement to drive adoption, retention, and revenue.","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Enter your email address","depth":14,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Get a Demo","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"coming soon Userpilot AI","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"coming soon","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot AI","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"In-app Engagement","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-app Engagement","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Product Analytics","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Analytics","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"User Feedback","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Session Replay","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Session Replay","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Join 1,000+ Companies Accelerating Product Growth With Userpilot.","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Introducing Lia","depth":13,"bounds":{"left":0.08541667,"top":0.18555556,"width":0.06875,"height":0.02},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Userpilot’s AI Agent for Product Growth","depth":11,"bounds":{"left":0.058333334,"top":0.23444444,"width":0.55,"height":0.04},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot’s AI Agent for Product Growth","depth":12,"bounds":{"left":0.058333334,"top":0.23333333,"width":0.37361112,"height":0.04111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.","depth":12,"bounds":{"left":0.058333334,"top":0.29555556,"width":0.49166667,"height":0.05111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about Lia","depth":11,"bounds":{"left":0.058333334,"top":0.36444443,"width":0.14791666,"height":0.05111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about Lia","depth":12,"bounds":{"left":0.07638889,"top":0.37888888,"width":0.11180556,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"User Onboarding","depth":10,"bounds":{"left":0.035416666,"top":0.51555556,"width":0.24236111,"height":0.057777777},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Onboarding","depth":11,"bounds":{"left":0.035416666,"top":0.5144445,"width":0.24236111,"height":0.06},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Guide new users through your product and reduce time-to-value.","depth":11,"bounds":{"left":0.035416666,"top":0.6155556,"width":0.3986111,"height":0.093333334},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Help existing users discover new features contextually.","depth":11,"bounds":{"left":0.035416666,"top":0.66555554,"width":0.41041666,"height":0.14222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See User Onboarding Solutions","depth":10,"bounds":{"left":0.035416666,"top":0.8466667,"width":0.20208333,"height":0.054444443},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See User Onboarding Solutions","depth":11,"bounds":{"left":0.05347222,"top":0.86333334,"width":0.16597222,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product Analytics","depth":10,"bounds":{"left":0.6166667,"top":0.9011111,"width":0.25208333,"height":0.057777777},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product Analytics","depth":11,"bounds":{"left":0.6166667,"top":0.9,"width":0.25208333,"height":0.06},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Understand user behavior across the product journey.","depth":11,"bounds":{"left":0.6166667,"top":1.0,"width":0.38333333,"height":-0.0011111498},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Generate custom reports to answer any product question.","depth":11,"bounds":{"left":0.6166667,"top":1.0,"width":0.38333333,"height":-0.051111102},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See Analytics Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See Analytics Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"User Feedback","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Feedback","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Capture and analyze user sentiment at scale.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Understand how your users really feel with contextual Microsurveys.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See User Feedback Tools","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See User Feedback Tools","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Session Replay","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Session Replay","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn how users interact with your product.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See Session Replay Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See Session Replay Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Userpilot for Mobile","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot for Mobile","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use mobile-first UI patterns.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Onboard users, run surveys, and track product metrics on native mobile devices.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore Mobile Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore Mobile Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Rally Your Whole Team Around Your Product Growth Goals.","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Rally Your Whole Team Around Your Product Growth Goals.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Start 14 Days Free Trial","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start 14 Days Free Trial","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No credit card required","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Kontentino improved New User Activation Rate by 10% in 1 month","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Kontentino improved New User Activation Rate by 10% in 1 month","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Integrate Userpilot with your favorite tech stack","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Integrate Userpilot with your favorite tech stack","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn More","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn More","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Unlock the Power of Product-Led Growth","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unlock the Power of Product-Led Growth","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Best practices to help you","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"activate more users, increase user engagement","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"drive more product growth.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Userpilot Blog Learn about product growth, good UX and the latest trends in product management.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Userpilot Blog","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot Blog","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn about product growth, good UX and the latest trends in product management.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Read","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Upcoming Webinars","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upcoming Webinars","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upcoming live webinars, on-demand videos and webcasts.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Watch","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Watch","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Product Drive Conference","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product Drive Conference","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn from industry leaders and stay up-to-date on the latest trends in product growth.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Connect","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Connect","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Take Your Product Experience to the Next Level","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Get a Demo","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Get a Demo","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Analytics","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Analytics","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Engagement","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Engagement","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Feedback","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Company","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Company","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Events","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Events","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Careers","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Careers","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customers","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customers","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Contact Us","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Contact Us","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"About Us","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"About Us","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Use Cases","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use Cases","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Onboarding","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Onboarding","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Adoption","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Adoption","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customer Retention","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer Retention","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Led Growth","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Led Growth","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"In-App Support","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-App Support","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Roles","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Roles","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Growth","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Growth","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Marketing","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Marketing","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Management","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Management","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"UX Design","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"UX Design","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Resources","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resources","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Blog","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Blog","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Adoption School","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Adoption School","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Drive","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Drive","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SaaS Onboarding Research","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SaaS Onboarding Research","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Case Studies","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Case Studies","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sitemap","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sitemap","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Support","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Support","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Help Center","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help Center","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"System Status","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"System Status","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Trust Center","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Trust Center","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Read more","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Read more","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Onboarding","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Onboarding","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Tours","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Tours","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customer Success","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer Success","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Behavior Tracking","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Behavior Tracking","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"In-App Guidance","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-App Guidance","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Microsurveys for SaaS Guide","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Microsurveys for SaaS Guide","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Interactive User Guides","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Interactive User Guides","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"© 2026 Userpilot. All rights reserved","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Terms of Use","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Terms of Use","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Privacy Policy","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Privacy Policy","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Your consent preferences for tracking technologies","depth":6,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your consent preferences for tracking technologies","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open live chat","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-7510561378842204685
|
9011094158866876738
|
visual_change
|
accessibility
|
NULL
|
Platform Team - Backlog - Jira
Service-Desk - Queu Platform Team - Backlog - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Inbox (1,550) - [EMAIL] - Jiminny Mail
For you - Confluence
For you - Confluence
Lukas Kovalik - Time Off
Lukas Kovalik - Time Off
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Userpilot
Platform
Platform
Solutions
Solutions
Pricing
Pricing
Integrations
Integrations
Resources
Resources
Customers
Customers
Free Trial
Free Trial
Log in
Log in
Get a Demo
Get a Demo
Drive Product Growth with
Drive Product Growth with
User Insights.
User Engagement.
User Feedback.
Leverage user insights & in-app engagement to drive adoption, retention, and revenue.
Enter your email address
Get a Demo
coming soon Userpilot AI
coming soon
Userpilot AI
In-app Engagement
In-app Engagement
Product Analytics
Product Analytics
User Feedback
User Feedback
Session Replay
Session Replay
Join 1,000+ Companies Accelerating Product Growth With Userpilot.
Introducing Lia
Userpilot’s AI Agent for Product Growth
Userpilot’s AI Agent for Product Growth
Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.
Learn more about Lia
Learn more about Lia
User Onboarding
User Onboarding
Guide new users through your product and reduce time-to-value.
Help existing users discover new features contextually.
See User Onboarding Solutions
See User Onboarding Solutions
Product Analytics
Product Analytics
Understand user behavior across the product journey.
Generate custom reports to answer any product question.
See Analytics Features
See Analytics Features
User Feedback
User Feedback
Capture and analyze user sentiment at scale.
Understand how your users really feel with contextual Microsurveys.
See User Feedback Tools
See User Feedback Tools
Session Replay
Session Replay
Learn how users interact with your product.
Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.
See Session Replay Features
See Session Replay Features
Userpilot for Mobile
Userpilot for Mobile
Use mobile-first UI patterns.
Onboard users, run surveys, and track product metrics on native mobile devices.
Explore Mobile Features
Explore Mobile Features
Rally Your Whole Team Around Your Product Growth Goals.
Rally Your Whole Team Around Your Product Growth Goals.
Start 14 Days Free Trial
Start 14 Days Free Trial
No credit card required
Kontentino improved New User Activation Rate by 10% in 1 month
Kontentino improved New User Activation Rate by 10% in 1 month
“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”
Integrate Userpilot with your favorite tech stack
Integrate Userpilot with your favorite tech stack
Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.
Learn More
Learn More
Unlock the Power of Product-Led Growth
Unlock the Power of Product-Led Growth
Best practices to help you
activate more users, increase user engagement
and
drive more product growth.
Userpilot Blog Learn about product growth, good UX and the latest trends in product management.
Userpilot Blog
Userpilot Blog
Learn about product growth, good UX and the latest trends in product management.
Read
Read
Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.
Upcoming Webinars
Upcoming Webinars
Upcoming live webinars, on-demand videos and webcasts.
Watch
Watch
Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Product Drive Conference
Product Drive Conference
Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Connect
Connect
Take Your Product Experience to the Next Level
Get a Demo
Get a Demo
Product
Product
Product Analytics
Product Analytics
User Engagement
User Engagement
User Feedback
User Feedback
Company
Company
Events
Events
Careers
Careers
Customers
Customers
Contact Us
Contact Us
About Us
About Us
Use Cases
Use Cases
User Onboarding
User Onboarding
Product Adoption
Product Adoption
Customer Retention
Customer Retention
Product Led Growth
Product Led Growth
In-App Support
In-App Support
Roles
Roles
Product Growth
Product Growth
Product Marketing
Product Marketing
Product Management
Product Management
UX Design
UX Design
Resources
Resources
Blog
Blog
Product Adoption School
Product Adoption School
Product Drive
Product Drive
SaaS Onboarding Research
SaaS Onboarding Research
Case Studies
Case Studies
Sitemap
Sitemap
Support
Support
Help Center
Help Center
System Status
System Status
Trust Center
Trust Center
Read more
Read more
User Onboarding
User Onboarding
Product Tours
Product Tours
Customer Success
Customer Success
User Behavior Tracking
User Behavior Tracking
In-App Guidance
In-App Guidance
Microsurveys for SaaS Guide
Microsurveys for SaaS Guide
Interactive User Guides
Interactive User Guides
© 2026 Userpilot. All rights reserved
Terms of Use
Terms of Use
Privacy Policy
Privacy Policy
Your consent preferences for tracking technologies
Your consent preferences for tracking technologies
Open live chat...
|
NULL
|
|
19315
|
411
|
10
|
2026-04-15T07:31:05.988290+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-15/1776 /Users/lukas/.screenpipe/data/data/2026-04-15/1776238265988_m1.jpg...
|
Firefox
|
Product Growth Platform | Userpilot — Work
|
1
|
userpilot.com
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Team - Backlog - Jira
Service-Desk - Queu Platform Team - Backlog - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Inbox (1,550) - [EMAIL] - Jiminny Mail
For you - Confluence
For you - Confluence
Lukas Kovalik - Time Off
Lukas Kovalik - Time Off
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Userpilot
Platform
Platform
Solutions
Solutions
Pricing
Pricing
Integrations
Integrations
Resources
Resources
Customers
Customers
Free Trial
Free Trial
Log in
Log in
Get a Demo
Get a Demo
Drive Product Growth with
Drive Product Growth with
User Insights.
User Engagement.
User Feedback.
Leverage user insights & in-app engagement to drive adoption, retention, and revenue.
Enter your email address
Get a Demo
coming soon Userpilot AI
coming soon
Userpilot AI
In-app Engagement
In-app Engagement
Product Analytics
Product Analytics
User Feedback
User Feedback
Session Replay
Session Replay
Join 1,000+ Companies Accelerating Product Growth With Userpilot.
Introducing Lia
Userpilot’s AI Agent for Product Growth
Userpilot’s AI Agent for Product Growth
Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.
Learn more about Lia
Learn more about Lia
User Onboarding
User Onboarding
Guide new users through your product and reduce time-to-value.
Help existing users discover new features contextually.
See User Onboarding Solutions
See User Onboarding Solutions
Product Analytics
Product Analytics
Understand user behavior across the product journey.
Generate custom reports to answer any product question.
See Analytics Features
See Analytics Features
User Feedback
User Feedback
Capture and analyze user sentiment at scale.
Understand how your users really feel with contextual Microsurveys.
See User Feedback Tools
See User Feedback Tools
Session Replay
Session Replay
Learn how users interact with your product.
Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.
See Session Replay Features
See Session Replay Features
Userpilot for Mobile
Userpilot for Mobile
Use mobile-first UI patterns.
Onboard users, run surveys, and track product metrics on native mobile devices.
Explore Mobile Features
Explore Mobile Features
Rally Your Whole Team Around Your Product Growth Goals.
Rally Your Whole Team Around Your Product Growth Goals.
Start 14 Days Free Trial
Start 14 Days Free Trial
No credit card required
Kontentino improved New User Activation Rate by 10% in 1 month
Kontentino improved New User Activation Rate by 10% in 1 month
“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”
Integrate Userpilot with your favorite tech stack
Integrate Userpilot with your favorite tech stack
Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.
Learn More
Learn More
Unlock the Power of Product-Led Growth
Unlock the Power of Product-Led Growth
Best practices to help you
activate more users, increase user engagement
and
drive more product growth.
Userpilot Blog Learn about product growth, good UX and the latest trends in product management.
Userpilot Blog
Userpilot Blog
Learn about product growth, good UX and the latest trends in product management.
Read
Read
Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.
Upcoming Webinars
Upcoming Webinars
Upcoming live webinars, on-demand videos and webcasts.
Watch
Watch
Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Product Drive Conference
Product Drive Conference
Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Connect
Connect
Take Your Product Experience to the Next Level
Get a Demo
Get a Demo
Product
Product
Product Analytics
Product Analytics
User Engagement
User Engagement
User Feedback
User Feedback
Company
Company
Events
Events
Careers
Careers
Customers
Customers
Contact Us
Contact Us
About Us
About Us
Use Cases
Use Cases
User Onboarding
User Onboarding
Product Adoption
Product Adoption
Customer Retention
Customer Retention
Product Led Growth
Product Led Growth
In-App Support
In-App Support
Roles
Roles
Product Growth
Product Growth
Product Marketing
Product Marketing
Product Management
Product Management
UX Design
UX Design
Resources
Resources
Blog
Blog
Product Adoption School
Product Adoption School
Product Drive
Product Drive
SaaS Onboarding Research
SaaS Onboarding Research
Case Studies
Case Studies
Sitemap
Sitemap
Support
Support
Help Center
Help Center
System Status
System Status
Trust Center
Trust Center
Read more
Read more
User Onboarding
User Onboarding
Product Tours
Product Tours
Customer Success
Customer Success
User Behavior Tracking
User Behavior Tracking
In-App Guidance
In-App Guidance
Microsurveys for SaaS Guide
Microsurveys for SaaS Guide
Interactive User Guides
Interactive User Guides
© 2026 Userpilot. All rights reserved
Terms of Use
Terms of Use
Privacy Policy
Privacy Policy
Your consent preferences for tracking technologies
Your consent preferences for tracking technologies
Open live chat...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Team - Backlog - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox (1,550) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"For you - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Lukas Kovalik - Time Off","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lukas Kovalik - Time Off","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Product Growth Platform | Userpilot","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Product Growth Platform | Userpilot","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Userpilot","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Platform","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Solutions","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Solutions","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pricing","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pricing","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Integrations","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Integrations","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Resources","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Resources","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customers","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customers","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Free Trial","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Free Trial","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Log in","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Log in","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Get a Demo","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Get a Demo","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Drive Product Growth with","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Drive Product Growth with","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Insights.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Engagement.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Feedback.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Leverage user insights & in-app engagement to drive adoption, retention, and revenue.","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Enter your email address","depth":14,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Get a Demo","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"coming soon Userpilot AI","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"coming soon","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot AI","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"In-app Engagement","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-app Engagement","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Product Analytics","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Analytics","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"User Feedback","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Session Replay","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Session Replay","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Join 1,000+ Companies Accelerating Product Growth With Userpilot.","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Introducing Lia","depth":13,"bounds":{"left":0.08541667,"top":0.18555556,"width":0.06875,"height":0.02},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Userpilot’s AI Agent for Product Growth","depth":11,"bounds":{"left":0.058333334,"top":0.23444444,"width":0.55,"height":0.04},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot’s AI Agent for Product Growth","depth":12,"bounds":{"left":0.058333334,"top":0.23333333,"width":0.37361112,"height":0.04111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.","depth":12,"bounds":{"left":0.058333334,"top":0.29555556,"width":0.49166667,"height":0.05111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about Lia","depth":11,"bounds":{"left":0.058333334,"top":0.36444443,"width":0.14791666,"height":0.05111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about Lia","depth":12,"bounds":{"left":0.07638889,"top":0.37888888,"width":0.11180556,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"User Onboarding","depth":10,"bounds":{"left":0.035416666,"top":0.51555556,"width":0.24236111,"height":0.057777777},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Onboarding","depth":11,"bounds":{"left":0.035416666,"top":0.5144445,"width":0.24236111,"height":0.06},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Guide new users through your product and reduce time-to-value.","depth":11,"bounds":{"left":0.035416666,"top":0.6155556,"width":0.3986111,"height":0.093333334},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Help existing users discover new features contextually.","depth":11,"bounds":{"left":0.035416666,"top":0.66555554,"width":0.41041666,"height":0.14222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See User Onboarding Solutions","depth":10,"bounds":{"left":0.035416666,"top":0.8466667,"width":0.20208333,"height":0.054444443},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See User Onboarding Solutions","depth":11,"bounds":{"left":0.05347222,"top":0.86333334,"width":0.16597222,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product Analytics","depth":10,"bounds":{"left":0.6166667,"top":0.9011111,"width":0.25208333,"height":0.057777777},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product Analytics","depth":11,"bounds":{"left":0.6166667,"top":0.9,"width":0.25208333,"height":0.06},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Understand user behavior across the product journey.","depth":11,"bounds":{"left":0.6166667,"top":1.0,"width":0.38333333,"height":-0.0011111498},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Generate custom reports to answer any product question.","depth":11,"bounds":{"left":0.6166667,"top":1.0,"width":0.38333333,"height":-0.051111102},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See Analytics Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See Analytics Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"User Feedback","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Feedback","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Capture and analyze user sentiment at scale.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Understand how your users really feel with contextual Microsurveys.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See User Feedback Tools","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See User Feedback Tools","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Session Replay","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Session Replay","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn how users interact with your product.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See Session Replay Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See Session Replay Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Userpilot for Mobile","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot for Mobile","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use mobile-first UI patterns.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Onboard users, run surveys, and track product metrics on native mobile devices.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore Mobile Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore Mobile Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Rally Your Whole Team Around Your Product Growth Goals.","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Rally Your Whole Team Around Your Product Growth Goals.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Start 14 Days Free Trial","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start 14 Days Free Trial","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No credit card required","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Kontentino improved New User Activation Rate by 10% in 1 month","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Kontentino improved New User Activation Rate by 10% in 1 month","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Integrate Userpilot with your favorite tech stack","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Integrate Userpilot with your favorite tech stack","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn More","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn More","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Unlock the Power of Product-Led Growth","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unlock the Power of Product-Led Growth","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Best practices to help you","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"activate more users, increase user engagement","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"drive more product growth.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Userpilot Blog Learn about product growth, good UX and the latest trends in product management.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Userpilot Blog","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot Blog","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn about product growth, good UX and the latest trends in product management.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Read","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Upcoming Webinars","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upcoming Webinars","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upcoming live webinars, on-demand videos and webcasts.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Watch","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Watch","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Product Drive Conference","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product Drive Conference","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn from industry leaders and stay up-to-date on the latest trends in product growth.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Connect","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Connect","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Take Your Product Experience to the Next Level","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Get a Demo","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Get a Demo","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Analytics","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Analytics","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Engagement","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Engagement","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Feedback","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Company","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Company","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Events","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Events","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Careers","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Careers","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customers","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customers","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Contact Us","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Contact Us","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"About Us","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"About Us","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Use Cases","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use Cases","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Onboarding","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Onboarding","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Adoption","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Adoption","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customer Retention","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer Retention","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Led Growth","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Led Growth","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"In-App Support","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-App Support","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Roles","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Roles","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Growth","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Growth","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Marketing","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Marketing","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Management","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Management","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"UX Design","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"UX Design","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Resources","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resources","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Blog","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Blog","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Adoption School","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Adoption School","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Drive","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Drive","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SaaS Onboarding Research","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SaaS Onboarding Research","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Case Studies","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Case Studies","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sitemap","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sitemap","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Support","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Support","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Help Center","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help Center","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"System Status","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"System Status","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Trust Center","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Trust Center","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Read more","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Read more","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Onboarding","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Onboarding","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Tours","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Tours","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customer Success","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer Success","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Behavior Tracking","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Behavior Tracking","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"In-App Guidance","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-App Guidance","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Microsurveys for SaaS Guide","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Microsurveys for SaaS Guide","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Interactive User Guides","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Interactive User Guides","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"© 2026 Userpilot. All rights reserved","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Terms of Use","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Terms of Use","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Privacy Policy","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Privacy Policy","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Your consent preferences for tracking technologies","depth":6,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your consent preferences for tracking technologies","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open live chat","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-7510561378842204685
|
9011094158866876738
|
visual_change
|
accessibility
|
NULL
|
Platform Team - Backlog - Jira
Service-Desk - Queu Platform Team - Backlog - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Inbox (1,550) - [EMAIL] - Jiminny Mail
For you - Confluence
For you - Confluence
Lukas Kovalik - Time Off
Lukas Kovalik - Time Off
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Userpilot
Platform
Platform
Solutions
Solutions
Pricing
Pricing
Integrations
Integrations
Resources
Resources
Customers
Customers
Free Trial
Free Trial
Log in
Log in
Get a Demo
Get a Demo
Drive Product Growth with
Drive Product Growth with
User Insights.
User Engagement.
User Feedback.
Leverage user insights & in-app engagement to drive adoption, retention, and revenue.
Enter your email address
Get a Demo
coming soon Userpilot AI
coming soon
Userpilot AI
In-app Engagement
In-app Engagement
Product Analytics
Product Analytics
User Feedback
User Feedback
Session Replay
Session Replay
Join 1,000+ Companies Accelerating Product Growth With Userpilot.
Introducing Lia
Userpilot’s AI Agent for Product Growth
Userpilot’s AI Agent for Product Growth
Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.
Learn more about Lia
Learn more about Lia
User Onboarding
User Onboarding
Guide new users through your product and reduce time-to-value.
Help existing users discover new features contextually.
See User Onboarding Solutions
See User Onboarding Solutions
Product Analytics
Product Analytics
Understand user behavior across the product journey.
Generate custom reports to answer any product question.
See Analytics Features
See Analytics Features
User Feedback
User Feedback
Capture and analyze user sentiment at scale.
Understand how your users really feel with contextual Microsurveys.
See User Feedback Tools
See User Feedback Tools
Session Replay
Session Replay
Learn how users interact with your product.
Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.
See Session Replay Features
See Session Replay Features
Userpilot for Mobile
Userpilot for Mobile
Use mobile-first UI patterns.
Onboard users, run surveys, and track product metrics on native mobile devices.
Explore Mobile Features
Explore Mobile Features
Rally Your Whole Team Around Your Product Growth Goals.
Rally Your Whole Team Around Your Product Growth Goals.
Start 14 Days Free Trial
Start 14 Days Free Trial
No credit card required
Kontentino improved New User Activation Rate by 10% in 1 month
Kontentino improved New User Activation Rate by 10% in 1 month
“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”
Integrate Userpilot with your favorite tech stack
Integrate Userpilot with your favorite tech stack
Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.
Learn More
Learn More
Unlock the Power of Product-Led Growth
Unlock the Power of Product-Led Growth
Best practices to help you
activate more users, increase user engagement
and
drive more product growth.
Userpilot Blog Learn about product growth, good UX and the latest trends in product management.
Userpilot Blog
Userpilot Blog
Learn about product growth, good UX and the latest trends in product management.
Read
Read
Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.
Upcoming Webinars
Upcoming Webinars
Upcoming live webinars, on-demand videos and webcasts.
Watch
Watch
Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Product Drive Conference
Product Drive Conference
Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Connect
Connect
Take Your Product Experience to the Next Level
Get a Demo
Get a Demo
Product
Product
Product Analytics
Product Analytics
User Engagement
User Engagement
User Feedback
User Feedback
Company
Company
Events
Events
Careers
Careers
Customers
Customers
Contact Us
Contact Us
About Us
About Us
Use Cases
Use Cases
User Onboarding
User Onboarding
Product Adoption
Product Adoption
Customer Retention
Customer Retention
Product Led Growth
Product Led Growth
In-App Support
In-App Support
Roles
Roles
Product Growth
Product Growth
Product Marketing
Product Marketing
Product Management
Product Management
UX Design
UX Design
Resources
Resources
Blog
Blog
Product Adoption School
Product Adoption School
Product Drive
Product Drive
SaaS Onboarding Research
SaaS Onboarding Research
Case Studies
Case Studies
Sitemap
Sitemap
Support
Support
Help Center
Help Center
System Status
System Status
Trust Center
Trust Center
Read more
Read more
User Onboarding
User Onboarding
Product Tours
Product Tours
Customer Success
Customer Success
User Behavior Tracking
User Behavior Tracking
In-App Guidance
In-App Guidance
Microsurveys for SaaS Guide
Microsurveys for SaaS Guide
Interactive User Guides
Interactive User Guides
© 2026 Userpilot. All rights reserved
Terms of Use
Terms of Use
Privacy Policy
Privacy Policy
Your consent preferences for tracking technologies
Your consent preferences for tracking technologies
Open live chat...
|
19312
|
|
19322
|
411
|
12
|
2026-04-15T07:31:24.145805+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-15/1776 /Users/lukas/.screenpipe/data/data/2026-04-15/1776238284145_m1.jpg...
|
Firefox
|
Product Growth Platform | Userpilot — Work
|
1
|
userpilot.com
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Team - Backlog - Jira
Service-Desk - Queu Platform Team - Backlog - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Inbox (1,550) - [EMAIL] - Jiminny Mail
For you - Confluence
For you - Confluence
Lukas Kovalik - Time Off
Lukas Kovalik - Time Off
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Userpilot
Platform
Platform
Solutions
Solutions
Pricing
Pricing
Integrations
Integrations
Resources
Resources
Customers
Customers
Free Trial
Free Trial
Log in
Log in
Get a Demo
Get a Demo
Drive Product Growth with
Drive Product Growth with
User Insights.
User Engagement.
User Feedback.
Leverage user insights & in-app engagement to drive adoption, retention, and revenue.
Enter your email address
Get a Demo
coming soon Userpilot AI
coming soon
Userpilot AI
In-app Engagement
In-app Engagement
Product Analytics
Product Analytics
User Feedback
User Feedback
Session Replay
Session Replay
Join 1,000+ Companies Accelerating Product Growth With Userpilot.
Introducing Lia
Userpilot’s AI Agent for Product Growth
Userpilot’s AI Agent for Product Growth
Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.
Learn more about Lia
Learn more about Lia
User Onboarding
User Onboarding
Guide new users through your product and reduce time-to-value.
Help existing users discover new features contextually.
See User Onboarding Solutions
See User Onboarding Solutions
Product Analytics
Product Analytics
Understand user behavior across the product journey.
Generate custom reports to answer any product question.
See Analytics Features
See Analytics Features
User Feedback
User Feedback
Capture and analyze user sentiment at scale.
Understand how your users really feel with contextual Microsurveys.
See User Feedback Tools
See User Feedback Tools
Session Replay
Session Replay
Learn how users interact with your product.
Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.
See Session Replay Features
See Session Replay Features
Userpilot for Mobile
Userpilot for Mobile
Use mobile-first UI patterns.
Onboard users, run surveys, and track product metrics on native mobile devices.
Explore Mobile Features
Explore Mobile Features
Rally Your Whole Team Around Your Product Growth Goals.
Rally Your Whole Team Around Your Product Growth Goals.
Start 14 Days Free Trial
Start 14 Days Free Trial
No credit card required
Kontentino improved New User Activation Rate by 10% in 1 month
Kontentino improved New User Activation Rate by 10% in 1 month
“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”
Integrate Userpilot with your favorite tech stack
Integrate Userpilot with your favorite tech stack
Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.
Learn More
Learn More
Unlock the Power of Product-Led Growth
Unlock the Power of Product-Led Growth
Best practices to help you
activate more users, increase user engagement
and
drive more product growth.
Userpilot Blog Learn about product growth, good UX and the latest trends in product management.
Userpilot Blog
Userpilot Blog
Learn about product growth, good UX and the latest trends in product management.
Read
Read
Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.
Upcoming Webinars
Upcoming Webinars
Upcoming live webinars, on-demand videos and webcasts.
Watch
Watch
Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Product Drive Conference
Product Drive Conference
Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Connect
Connect
Take Your Product Experience to the Next Level
Get a Demo
Get a Demo
Product
Product
Product Analytics
Product Analytics
User Engagement
User Engagement
User Feedback
User Feedback
Company
Company
Events
Events
Careers
Careers
Customers
Customers
Contact Us
Contact Us
About Us
About Us
Use Cases
Use Cases
User Onboarding
User Onboarding
Product Adoption
Product Adoption
Customer Retention
Customer Retention
Product Led Growth
Product Led Growth
In-App Support
In-App Support
Roles
Roles
Product Growth
Product Growth
Product Marketing
Product Marketing
Product Management
Product Management
UX Design
UX Design
Resources
Resources
Blog
Blog
Product Adoption School
Product Adoption School
Product Drive
Product Drive
SaaS Onboarding Research
SaaS Onboarding Research
Case Studies
Case Studies
Sitemap
Sitemap
Support
Support
Help Center
Help Center
System Status
System Status
Trust Center
Trust Center
Read more
Read more
User Onboarding
User Onboarding
Product Tours
Product Tours
Customer Success
Customer Success
User Behavior Tracking
User Behavior Tracking
In-App Guidance
In-App Guidance...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Team - Backlog - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox (1,550) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"For you - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Lukas Kovalik - Time Off","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lukas Kovalik - Time Off","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Product Growth Platform | Userpilot","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Product Growth Platform | Userpilot","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Userpilot","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Platform","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Solutions","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Solutions","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pricing","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pricing","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Integrations","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Integrations","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Resources","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Resources","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customers","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customers","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Free Trial","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Free Trial","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Log in","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Log in","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Get a Demo","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Get a Demo","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Drive Product Growth with","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Drive Product Growth with","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Insights.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Engagement.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Feedback.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Leverage user insights & in-app engagement to drive adoption, retention, and revenue.","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Enter your email address","depth":14,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Get a Demo","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"coming soon Userpilot AI","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"coming soon","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot AI","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"In-app Engagement","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-app Engagement","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Product Analytics","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Analytics","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"User Feedback","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Session Replay","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Session Replay","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Join 1,000+ Companies Accelerating Product Growth With Userpilot.","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Introducing Lia","depth":13,"bounds":{"left":0.08541667,"top":0.18555556,"width":0.06875,"height":0.02},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Userpilot’s AI Agent for Product Growth","depth":11,"bounds":{"left":0.058333334,"top":0.23444444,"width":0.55,"height":0.04},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot’s AI Agent for Product Growth","depth":12,"bounds":{"left":0.058333334,"top":0.23333333,"width":0.37361112,"height":0.04111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.","depth":12,"bounds":{"left":0.058333334,"top":0.29555556,"width":0.49166667,"height":0.05111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about Lia","depth":11,"bounds":{"left":0.058333334,"top":0.36444443,"width":0.14791666,"height":0.05111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about Lia","depth":12,"bounds":{"left":0.07638889,"top":0.37888888,"width":0.11180556,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"User Onboarding","depth":10,"bounds":{"left":0.035416666,"top":0.51555556,"width":0.24236111,"height":0.057777777},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Onboarding","depth":11,"bounds":{"left":0.035416666,"top":0.5144445,"width":0.24236111,"height":0.06},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Guide new users through your product and reduce time-to-value.","depth":11,"bounds":{"left":0.035416666,"top":0.6155556,"width":0.3986111,"height":0.093333334},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Help existing users discover new features contextually.","depth":11,"bounds":{"left":0.035416666,"top":0.66555554,"width":0.41041666,"height":0.14222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See User Onboarding Solutions","depth":10,"bounds":{"left":0.035416666,"top":0.8466667,"width":0.20208333,"height":0.054444443},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See User Onboarding Solutions","depth":11,"bounds":{"left":0.05347222,"top":0.86333334,"width":0.16597222,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product Analytics","depth":10,"bounds":{"left":0.6166667,"top":0.9011111,"width":0.25208333,"height":0.057777777},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product Analytics","depth":11,"bounds":{"left":0.6166667,"top":0.9,"width":0.25208333,"height":0.06},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Understand user behavior across the product journey.","depth":11,"bounds":{"left":0.6166667,"top":1.0,"width":0.38333333,"height":-0.0011111498},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Generate custom reports to answer any product question.","depth":11,"bounds":{"left":0.6166667,"top":1.0,"width":0.38333333,"height":-0.051111102},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See Analytics Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See Analytics Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"User Feedback","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Feedback","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Capture and analyze user sentiment at scale.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Understand how your users really feel with contextual Microsurveys.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See User Feedback Tools","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See User Feedback Tools","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Session Replay","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Session Replay","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn how users interact with your product.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See Session Replay Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See Session Replay Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Userpilot for Mobile","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot for Mobile","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use mobile-first UI patterns.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Onboard users, run surveys, and track product metrics on native mobile devices.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore Mobile Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore Mobile Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Rally Your Whole Team Around Your Product Growth Goals.","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Rally Your Whole Team Around Your Product Growth Goals.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Start 14 Days Free Trial","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start 14 Days Free Trial","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No credit card required","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Kontentino improved New User Activation Rate by 10% in 1 month","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Kontentino improved New User Activation Rate by 10% in 1 month","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Integrate Userpilot with your favorite tech stack","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Integrate Userpilot with your favorite tech stack","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn More","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn More","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Unlock the Power of Product-Led Growth","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unlock the Power of Product-Led Growth","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Best practices to help you","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"activate more users, increase user engagement","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"drive more product growth.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Userpilot Blog Learn about product growth, good UX and the latest trends in product management.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Userpilot Blog","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot Blog","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn about product growth, good UX and the latest trends in product management.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Read","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Upcoming Webinars","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upcoming Webinars","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upcoming live webinars, on-demand videos and webcasts.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Watch","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Watch","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Product Drive Conference","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product Drive Conference","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn from industry leaders and stay up-to-date on the latest trends in product growth.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Connect","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Connect","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Take Your Product Experience to the Next Level","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Get a Demo","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Get a Demo","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Analytics","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Analytics","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Engagement","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Engagement","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Feedback","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Company","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Company","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Events","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Events","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Careers","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Careers","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customers","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customers","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Contact Us","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Contact Us","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"About Us","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"About Us","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Use Cases","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use Cases","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Onboarding","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Onboarding","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Adoption","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Adoption","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customer Retention","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer Retention","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Led Growth","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Led Growth","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"In-App Support","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-App Support","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Roles","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Roles","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Growth","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Growth","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Marketing","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Marketing","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Management","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Management","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"UX Design","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"UX Design","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Resources","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resources","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Blog","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Blog","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Adoption School","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Adoption School","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Drive","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Drive","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SaaS Onboarding Research","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SaaS Onboarding Research","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Case Studies","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Case Studies","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sitemap","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sitemap","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Support","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Support","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Help Center","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help Center","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"System Status","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"System Status","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Trust Center","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Trust Center","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Read more","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Read more","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Onboarding","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Onboarding","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Tours","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Tours","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customer Success","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer Success","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Behavior Tracking","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Behavior Tracking","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"In-App Guidance","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-App Guidance","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-8294317579908858051
|
9011092509867871554
|
visual_change
|
accessibility
|
NULL
|
Platform Team - Backlog - Jira
Service-Desk - Queu Platform Team - Backlog - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Inbox (1,550) - [EMAIL] - Jiminny Mail
For you - Confluence
For you - Confluence
Lukas Kovalik - Time Off
Lukas Kovalik - Time Off
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Userpilot
Platform
Platform
Solutions
Solutions
Pricing
Pricing
Integrations
Integrations
Resources
Resources
Customers
Customers
Free Trial
Free Trial
Log in
Log in
Get a Demo
Get a Demo
Drive Product Growth with
Drive Product Growth with
User Insights.
User Engagement.
User Feedback.
Leverage user insights & in-app engagement to drive adoption, retention, and revenue.
Enter your email address
Get a Demo
coming soon Userpilot AI
coming soon
Userpilot AI
In-app Engagement
In-app Engagement
Product Analytics
Product Analytics
User Feedback
User Feedback
Session Replay
Session Replay
Join 1,000+ Companies Accelerating Product Growth With Userpilot.
Introducing Lia
Userpilot’s AI Agent for Product Growth
Userpilot’s AI Agent for Product Growth
Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.
Learn more about Lia
Learn more about Lia
User Onboarding
User Onboarding
Guide new users through your product and reduce time-to-value.
Help existing users discover new features contextually.
See User Onboarding Solutions
See User Onboarding Solutions
Product Analytics
Product Analytics
Understand user behavior across the product journey.
Generate custom reports to answer any product question.
See Analytics Features
See Analytics Features
User Feedback
User Feedback
Capture and analyze user sentiment at scale.
Understand how your users really feel with contextual Microsurveys.
See User Feedback Tools
See User Feedback Tools
Session Replay
Session Replay
Learn how users interact with your product.
Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.
See Session Replay Features
See Session Replay Features
Userpilot for Mobile
Userpilot for Mobile
Use mobile-first UI patterns.
Onboard users, run surveys, and track product metrics on native mobile devices.
Explore Mobile Features
Explore Mobile Features
Rally Your Whole Team Around Your Product Growth Goals.
Rally Your Whole Team Around Your Product Growth Goals.
Start 14 Days Free Trial
Start 14 Days Free Trial
No credit card required
Kontentino improved New User Activation Rate by 10% in 1 month
Kontentino improved New User Activation Rate by 10% in 1 month
“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”
Integrate Userpilot with your favorite tech stack
Integrate Userpilot with your favorite tech stack
Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.
Learn More
Learn More
Unlock the Power of Product-Led Growth
Unlock the Power of Product-Led Growth
Best practices to help you
activate more users, increase user engagement
and
drive more product growth.
Userpilot Blog Learn about product growth, good UX and the latest trends in product management.
Userpilot Blog
Userpilot Blog
Learn about product growth, good UX and the latest trends in product management.
Read
Read
Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.
Upcoming Webinars
Upcoming Webinars
Upcoming live webinars, on-demand videos and webcasts.
Watch
Watch
Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Product Drive Conference
Product Drive Conference
Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Connect
Connect
Take Your Product Experience to the Next Level
Get a Demo
Get a Demo
Product
Product
Product Analytics
Product Analytics
User Engagement
User Engagement
User Feedback
User Feedback
Company
Company
Events
Events
Careers
Careers
Customers
Customers
Contact Us
Contact Us
About Us
About Us
Use Cases
Use Cases
User Onboarding
User Onboarding
Product Adoption
Product Adoption
Customer Retention
Customer Retention
Product Led Growth
Product Led Growth
In-App Support
In-App Support
Roles
Roles
Product Growth
Product Growth
Product Marketing
Product Marketing
Product Management
Product Management
UX Design
UX Design
Resources
Resources
Blog
Blog
Product Adoption School
Product Adoption School
Product Drive
Product Drive
SaaS Onboarding Research
SaaS Onboarding Research
Case Studies
Case Studies
Sitemap
Sitemap
Support
Support
Help Center
Help Center
System Status
System Status
Trust Center
Trust Center
Read more
Read more
User Onboarding
User Onboarding
Product Tours
Product Tours
Customer Success
Customer Success
User Behavior Tracking
User Behavior Tracking
In-App Guidance
In-App Guidance...
|
19317
|
|
19314
|
412
|
13
|
2026-04-15T07:31:03.822281+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-15/1776 /Users/lukas/.screenpipe/data/data/2026-04-15/1776238263822_m2.jpg...
|
Firefox
|
Product Growth Platform | Userpilot — Work
|
1
|
userpilot.com
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Team - Backlog - Jira
Service-Desk - Queu Platform Team - Backlog - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Inbox (1,550) - [EMAIL] - Jiminny Mail
For you - Confluence
For you - Confluence
Lukas Kovalik - Time Off
Lukas Kovalik - Time Off
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Userpilot
Platform
Platform
Solutions
Solutions
Pricing
Pricing
Integrations
Integrations
Resources
Resources
Customers
Customers
Free Trial
Free Trial
Log in
Log in
Get a Demo
Get a Demo
Drive Product Growth with
Drive Product Growth with
User Insights.
User Engagement.
User Feedback.
Leverage user insights & in-app engagement to drive adoption, retention, and revenue.
Enter your email address
Get a Demo
coming soon Userpilot AI
coming soon
Userpilot AI
In-app Engagement
In-app Engagement
Product Analytics
Product Analytics
User Feedback
User Feedback
Session Replay
Session Replay
Join 1,000+ Companies Accelerating Product Growth With Userpilot.
Introducing Lia
Userpilot’s AI Agent for Product Growth
Userpilot’s AI Agent for Product Growth
Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.
Learn more about Lia
Learn more about Lia
User Onboarding
User Onboarding
Guide new users through your product and reduce time-to-value.
Help existing users discover new features contextually.
See User Onboarding Solutions
See User Onboarding Solutions
Product Analytics
Product Analytics
Understand user behavior across the product journey.
Generate custom reports to answer any product question.
See Analytics Features
See Analytics Features
User Feedback
User Feedback
Capture and analyze user sentiment at scale.
Understand how your users really feel with contextual Microsurveys.
See User Feedback Tools
See User Feedback Tools
Session Replay
Session Replay
Learn how users interact with your product.
Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.
See Session Replay Features
See Session Replay Features
Userpilot for Mobile
Userpilot for Mobile
Use mobile-first UI patterns.
Onboard users, run surveys, and track product metrics on native mobile devices.
Explore Mobile Features
Explore Mobile Features
Rally Your Whole Team Around Your Product Growth Goals.
Rally Your Whole Team Around Your Product Growth Goals.
Start 14 Days Free Trial
Start 14 Days Free Trial
No credit card required
Kontentino improved New User Activation Rate by 10% in 1 month
Kontentino improved New User Activation Rate by 10% in 1 month
“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”
Integrate Userpilot with your favorite tech stack
Integrate Userpilot with your favorite tech stack
Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.
Learn More
Learn More
Unlock the Power of Product-Led Growth
Unlock the Power of Product-Led Growth
Best practices to help you
activate more users, increase user engagement
and
drive more product growth.
Userpilot Blog Learn about product growth, good UX and the latest trends in product management.
Userpilot Blog
Userpilot Blog
Learn about product growth, good UX and the latest trends in product management.
Read
Read
Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.
Upcoming Webinars
Upcoming Webinars
Upcoming live webinars, on-demand videos and webcasts.
Watch
Watch
Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Product Drive Conference
Product Drive Conference
Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Connect
Connect
Take Your Product Experience to the Next Level
Get a Demo
Get a Demo
Product
Product
Product Analytics
Product Analytics
User Engagement
User Engagement
User Feedback
User Feedback
Company
Company
Events
Events
Careers
Careers
Customers
Customers
Contact Us
Contact Us
About Us
About Us
Use Cases
Use Cases
User Onboarding
User Onboarding
Product Adoption
Product Adoption
Customer Retention
Customer Retention
Product Led Growth
Product Led Growth
In-App Support
In-App Support
Roles
Roles
Product Growth
Product Growth
Product Marketing
Product Marketing
Product Management
Product Management
UX Design
UX Design
Resources
Resources
Blog
Blog
Product Adoption School
Product Adoption School
Product Drive
Product Drive
SaaS Onboarding Research
SaaS Onboarding Research
Case Studies
Case Studies
Sitemap
Sitemap
Support
Support
Help Center
Help Center
System Status
System Status
Trust Center
Trust Center
Read more
Read more
User Onboarding
User Onboarding
Product Tours
Product Tours
Customer Success
Customer Success
User Behavior Tracking
User Behavior Tracking
In-App Guidance
In-App Guidance
Microsurveys for SaaS Guide
Microsurveys for SaaS Guide
Interactive User Guides
Interactive User Guides
© 2026 Userpilot. All rights reserved
Terms of Use
Terms of Use...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Team - Backlog - Jira","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.017578125,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.019921875,"top":0.045138888,"width":0.01796875,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.037890624,"top":0.045138888,"width":0.01796875,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"bounds":{"left":0.055859376,"top":0.045138888,"width":0.017578125,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.0734375,"top":0.045138888,"width":0.01796875,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox (1,550) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.00234375,"top":0.07361111,"width":0.017578125,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"For you - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.04296875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Lukas Kovalik - Time Off","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lukas Kovalik - Time Off","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.049609374,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Product Growth Platform | Userpilot","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Product Growth Platform | Userpilot","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.07304688,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.17430556,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.19791667,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Userpilot","depth":9,"bounds":{"left":0.2609375,"top":0.08680555,"width":0.08476563,"height":0.02013889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Platform","depth":12,"bounds":{"left":0.39765626,"top":0.07083333,"width":0.022265624,"height":0.05138889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform","depth":13,"bounds":{"left":0.39765626,"top":0.090277776,"width":0.022265624,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Solutions","depth":12,"bounds":{"left":0.43164062,"top":0.07083333,"width":0.024609376,"height":0.05138889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Solutions","depth":13,"bounds":{"left":0.43164062,"top":0.090277776,"width":0.024609376,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pricing","depth":12,"bounds":{"left":0.46796876,"top":0.07083333,"width":0.017578125,"height":0.05138889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pricing","depth":13,"bounds":{"left":0.46796876,"top":0.090277776,"width":0.017578125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Integrations","depth":12,"bounds":{"left":0.49726564,"top":0.07083333,"width":0.031640626,"height":0.05138889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Integrations","depth":13,"bounds":{"left":0.49726564,"top":0.090277776,"width":0.031640626,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Resources","depth":12,"bounds":{"left":0.540625,"top":0.07083333,"width":0.02734375,"height":0.05138889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Resources","depth":13,"bounds":{"left":0.540625,"top":0.090277776,"width":0.02734375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customers","depth":12,"bounds":{"left":0.5796875,"top":0.07083333,"width":0.028515626,"height":0.05138889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customers","depth":13,"bounds":{"left":0.5796875,"top":0.090277776,"width":0.028515626,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Free Trial","depth":12,"bounds":{"left":0.61992186,"top":0.07083333,"width":0.02265625,"height":0.05138889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Free Trial","depth":13,"bounds":{"left":0.61992186,"top":0.090277776,"width":0.02265625,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Log in","depth":12,"bounds":{"left":0.7515625,"top":0.09166667,"width":0.015234375,"height":0.013194445},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Log in","depth":13,"bounds":{"left":0.7515625,"top":0.09166667,"width":0.015234375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Get a Demo","depth":12,"bounds":{"left":0.7757813,"top":0.08263889,"width":0.0515625,"height":0.03125},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Get a Demo","depth":13,"bounds":{"left":0.7859375,"top":0.09166667,"width":0.03125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Drive Product Growth with","depth":9,"bounds":{"left":0.4234375,"top":0.1701389,"width":0.24140625,"height":0.041666668},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Drive Product Growth with","depth":10,"bounds":{"left":0.4234375,"top":0.1701389,"width":0.24140625,"height":0.04236111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Insights.","depth":11,"bounds":{"left":0.48242188,"top":0.2048611,"width":0.1234375,"height":0.04236111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Engagement.","depth":11,"bounds":{"left":0.4597656,"top":0.2048611,"width":0.16875,"height":0.04236111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Feedback.","depth":11,"bounds":{"left":0.47226563,"top":0.21875,"width":0.14375,"height":0.04236111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Leverage user insights & in-app engagement to drive adoption, retention, and revenue.","depth":10,"bounds":{"left":0.40273437,"top":0.28194445,"width":0.2828125,"height":0.015972223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Enter your email address","depth":14,"bounds":{"left":0.45546874,"top":0.33055556,"width":0.1171875,"height":0.03125},"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Get a Demo","depth":11,"bounds":{"left":0.57851565,"top":0.33055556,"width":0.054296874,"height":0.03125},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"coming soon Userpilot AI","depth":10,"bounds":{"left":0.38476562,"top":0.39375,"width":0.0421875,"height":0.013194445},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"coming soon","depth":12,"bounds":{"left":0.390625,"top":0.37222221,"width":0.03046875,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot AI","depth":11,"bounds":{"left":0.3953125,"top":0.39444444,"width":0.030078124,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"In-app Engagement","depth":10,"bounds":{"left":0.44023436,"top":0.39375,"width":0.06328125,"height":0.013194445},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-app Engagement","depth":11,"bounds":{"left":0.44921875,"top":0.39444444,"width":0.052734375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Product Analytics","depth":10,"bounds":{"left":0.5167969,"top":0.39375,"width":0.057421874,"height":0.013194445},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Analytics","depth":11,"bounds":{"left":0.5257813,"top":0.39444444,"width":0.046875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"User Feedback","depth":10,"bounds":{"left":0.5878906,"top":0.39375,"width":0.05078125,"height":0.013194445},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":11,"bounds":{"left":0.596875,"top":0.39444444,"width":0.040234376,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Session Replay","depth":10,"bounds":{"left":0.65234375,"top":0.39375,"width":0.051171876,"height":0.013194445},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Session Replay","depth":11,"bounds":{"left":0.66132814,"top":0.39444444,"width":0.040625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Join 1,000+ Companies Accelerating Product Growth With Userpilot.","depth":10,"bounds":{"left":0.40625,"top":0.8263889,"width":0.27578124,"height":0.019444445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Introducing Lia","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Userpilot’s AI Agent for Product Growth","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot’s AI Agent for Product Growth","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about Lia","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about Lia","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"User Onboarding","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Onboarding","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Guide new users through your product and reduce time-to-value.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Help existing users discover new features contextually.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See User Onboarding Solutions","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See User Onboarding Solutions","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product Analytics","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product Analytics","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Understand user behavior across the product journey.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Generate custom reports to answer any product question.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See Analytics Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See Analytics Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"User Feedback","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Feedback","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Capture and analyze user sentiment at scale.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Understand how your users really feel with contextual Microsurveys.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See User Feedback Tools","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See User Feedback Tools","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Session Replay","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Session Replay","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn how users interact with your product.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See Session Replay Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See Session Replay Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Userpilot for Mobile","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot for Mobile","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use mobile-first UI patterns.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Onboard users, run surveys, and track product metrics on native mobile devices.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore Mobile Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore Mobile Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Rally Your Whole Team Around Your Product Growth Goals.","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Rally Your Whole Team Around Your Product Growth Goals.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Start 14 Days Free Trial","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start 14 Days Free Trial","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No credit card required","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Kontentino improved New User Activation Rate by 10% in 1 month","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Kontentino improved New User Activation Rate by 10% in 1 month","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Integrate Userpilot with your favorite tech stack","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Integrate Userpilot with your favorite tech stack","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn More","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn More","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Unlock the Power of Product-Led Growth","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unlock the Power of Product-Led Growth","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Best practices to help you","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"activate more users, increase user engagement","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"drive more product growth.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Userpilot Blog Learn about product growth, good UX and the latest trends in product management.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Userpilot Blog","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot Blog","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn about product growth, good UX and the latest trends in product management.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Read","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Upcoming Webinars","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upcoming Webinars","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upcoming live webinars, on-demand videos and webcasts.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Watch","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Watch","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Product Drive Conference","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product Drive Conference","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn from industry leaders and stay up-to-date on the latest trends in product growth.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Connect","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Connect","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Take Your Product Experience to the Next Level","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Get a Demo","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Get a Demo","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Analytics","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Analytics","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Engagement","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Engagement","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Feedback","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Company","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Company","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Events","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Events","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Careers","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Careers","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customers","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customers","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Contact Us","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Contact Us","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"About Us","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"About Us","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Use Cases","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use Cases","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Onboarding","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Onboarding","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Adoption","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Adoption","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customer Retention","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer Retention","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Led Growth","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Led Growth","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"In-App Support","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-App Support","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Roles","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Roles","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Growth","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Growth","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Marketing","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Marketing","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Management","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Management","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"UX Design","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"UX Design","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Resources","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resources","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Blog","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Blog","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Adoption School","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Adoption School","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Drive","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Drive","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SaaS Onboarding Research","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SaaS Onboarding Research","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Case Studies","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Case Studies","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sitemap","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sitemap","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Support","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Support","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Help Center","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help Center","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"System Status","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"System Status","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Trust Center","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Trust Center","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Read more","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Read more","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Onboarding","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Onboarding","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Tours","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Tours","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customer Success","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer Success","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Behavior Tracking","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Behavior Tracking","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"In-App Guidance","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-App Guidance","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Microsurveys for SaaS Guide","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Microsurveys for SaaS Guide","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Interactive User Guides","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Interactive User Guides","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"© 2026 Userpilot. All rights reserved","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Terms of Use","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Terms of Use","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
6498654760291604584
|
9011091960111008066
|
visual_change
|
accessibility
|
NULL
|
Platform Team - Backlog - Jira
Service-Desk - Queu Platform Team - Backlog - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Inbox (1,550) - [EMAIL] - Jiminny Mail
For you - Confluence
For you - Confluence
Lukas Kovalik - Time Off
Lukas Kovalik - Time Off
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Userpilot
Platform
Platform
Solutions
Solutions
Pricing
Pricing
Integrations
Integrations
Resources
Resources
Customers
Customers
Free Trial
Free Trial
Log in
Log in
Get a Demo
Get a Demo
Drive Product Growth with
Drive Product Growth with
User Insights.
User Engagement.
User Feedback.
Leverage user insights & in-app engagement to drive adoption, retention, and revenue.
Enter your email address
Get a Demo
coming soon Userpilot AI
coming soon
Userpilot AI
In-app Engagement
In-app Engagement
Product Analytics
Product Analytics
User Feedback
User Feedback
Session Replay
Session Replay
Join 1,000+ Companies Accelerating Product Growth With Userpilot.
Introducing Lia
Userpilot’s AI Agent for Product Growth
Userpilot’s AI Agent for Product Growth
Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.
Learn more about Lia
Learn more about Lia
User Onboarding
User Onboarding
Guide new users through your product and reduce time-to-value.
Help existing users discover new features contextually.
See User Onboarding Solutions
See User Onboarding Solutions
Product Analytics
Product Analytics
Understand user behavior across the product journey.
Generate custom reports to answer any product question.
See Analytics Features
See Analytics Features
User Feedback
User Feedback
Capture and analyze user sentiment at scale.
Understand how your users really feel with contextual Microsurveys.
See User Feedback Tools
See User Feedback Tools
Session Replay
Session Replay
Learn how users interact with your product.
Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.
See Session Replay Features
See Session Replay Features
Userpilot for Mobile
Userpilot for Mobile
Use mobile-first UI patterns.
Onboard users, run surveys, and track product metrics on native mobile devices.
Explore Mobile Features
Explore Mobile Features
Rally Your Whole Team Around Your Product Growth Goals.
Rally Your Whole Team Around Your Product Growth Goals.
Start 14 Days Free Trial
Start 14 Days Free Trial
No credit card required
Kontentino improved New User Activation Rate by 10% in 1 month
Kontentino improved New User Activation Rate by 10% in 1 month
“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”
Integrate Userpilot with your favorite tech stack
Integrate Userpilot with your favorite tech stack
Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.
Learn More
Learn More
Unlock the Power of Product-Led Growth
Unlock the Power of Product-Led Growth
Best practices to help you
activate more users, increase user engagement
and
drive more product growth.
Userpilot Blog Learn about product growth, good UX and the latest trends in product management.
Userpilot Blog
Userpilot Blog
Learn about product growth, good UX and the latest trends in product management.
Read
Read
Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.
Upcoming Webinars
Upcoming Webinars
Upcoming live webinars, on-demand videos and webcasts.
Watch
Watch
Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Product Drive Conference
Product Drive Conference
Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Connect
Connect
Take Your Product Experience to the Next Level
Get a Demo
Get a Demo
Product
Product
Product Analytics
Product Analytics
User Engagement
User Engagement
User Feedback
User Feedback
Company
Company
Events
Events
Careers
Careers
Customers
Customers
Contact Us
Contact Us
About Us
About Us
Use Cases
Use Cases
User Onboarding
User Onboarding
Product Adoption
Product Adoption
Customer Retention
Customer Retention
Product Led Growth
Product Led Growth
In-App Support
In-App Support
Roles
Roles
Product Growth
Product Growth
Product Marketing
Product Marketing
Product Management
Product Management
UX Design
UX Design
Resources
Resources
Blog
Blog
Product Adoption School
Product Adoption School
Product Drive
Product Drive
SaaS Onboarding Research
SaaS Onboarding Research
Case Studies
Case Studies
Sitemap
Sitemap
Support
Support
Help Center
Help Center
System Status
System Status
Trust Center
Trust Center
Read more
Read more
User Onboarding
User Onboarding
Product Tours
Product Tours
Customer Success
Customer Success
User Behavior Tracking
User Behavior Tracking
In-App Guidance
In-App Guidance
Microsurveys for SaaS Guide
Microsurveys for SaaS Guide
Interactive User Guides
Interactive User Guides
© 2026 Userpilot. All rights reserved
Terms of Use
Terms of Use...
|
19313
|
|
19310
|
411
|
8
|
2026-04-15T07:30:53.874810+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-15/1776 /Users/lukas/.screenpipe/data/data/2026-04-15/1776238253874_m1.jpg...
|
Firefox
|
Product Growth Platform | Userpilot — Work
|
1
|
userpilot.com
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Team - Backlog - Jira
Service-Desk - Queu Platform Team - Backlog - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Inbox (1,550) - [EMAIL] - Jiminny Mail
For you - Confluence
For you - Confluence
Lukas Kovalik - Time Off
Lukas Kovalik - Time Off
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Userpilot
Platform
Platform
Solutions
Solutions
Pricing
Pricing
Integrations
Integrations
Resources
Resources
Customers
Customers
Free Trial
Free Trial
Log in
Log in
Get a Demo
Get a Demo
Drive Product Growth with
Drive Product Growth with
User Insights.
User Engagement.
User Feedback.
Leverage user insights & in-app engagement to drive adoption, retention, and revenue.
Enter your email address
Get a Demo
coming soon Userpilot AI
coming soon
Userpilot AI
In-app Engagement
In-app Engagement
Product Analytics
Product Analytics
User Feedback
User Feedback
Session Replay
Session Replay
Join 1,000+ Companies Accelerating Product Growth With Userpilot.
Introducing Lia
Userpilot’s AI Agent for Product Growth
Userpilot’s AI Agent for Product Growth
Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.
Learn more about Lia
Learn more about Lia
User Onboarding
User Onboarding
Guide new users through your product and reduce time-to-value.
Help existing users discover new features contextually.
See User Onboarding Solutions
See User Onboarding Solutions
Product Analytics
Product Analytics
Understand user behavior across the product journey.
Generate custom reports to answer any product question.
See Analytics Features
See Analytics Features
User Feedback
User Feedback
Capture and analyze user sentiment at scale.
Understand how your users really feel with contextual Microsurveys.
See User Feedback Tools
See User Feedback Tools
Session Replay
Session Replay
Learn how users interact with your product.
Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.
See Session Replay Features
See Session Replay Features
Userpilot for Mobile
Userpilot for Mobile
Use mobile-first UI patterns.
Onboard users, run surveys, and track product metrics on native mobile devices.
Explore Mobile Features
Explore Mobile Features
Rally Your Whole Team Around Your Product Growth Goals.
Rally Your Whole Team Around Your Product Growth Goals.
Start 14 Days Free Trial
Start 14 Days Free Trial
No credit card required
Kontentino improved New User Activation Rate by 10% in 1 month
Kontentino improved New User Activation Rate by 10% in 1 month
“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”
Integrate Userpilot with your favorite tech stack
Integrate Userpilot with your favorite tech stack
Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.
Learn More
Learn More
Unlock the Power of Product-Led Growth
Unlock the Power of Product-Led Growth
Best practices to help you
activate more users, increase user engagement
and
drive more product growth.
Userpilot Blog Learn about product growth, good UX and the latest trends in product management.
Userpilot Blog
Userpilot Blog
Learn about product growth, good UX and the latest trends in product management.
Read
Read
Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.
Upcoming Webinars
Upcoming Webinars
Upcoming live webinars, on-demand videos and webcasts.
Watch
Watch
Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Product Drive Conference
Product Drive Conference
Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Connect
Connect
Take Your Product Experience to the Next Level
Get a Demo
Get a Demo
Product
Product
Product Analytics
Product Analytics
User Engagement
User Engagement
User Feedback
User Feedback
Company
Company
Events
Events
Careers
Careers
Customers
Customers
Contact Us
Contact Us
About Us
About Us
Use Cases
Use Cases
User Onboarding
User Onboarding
Product Adoption
Product Adoption
Customer Retention
Customer Retention
Product Led Growth
Product Led Growth
In-App Support
In-App Support
Roles
Roles
Product Growth
Product Growth
Product Marketing
Product Marketing
Product Management
Product Management
UX Design
UX Design
Resources
Resources
Blog
Blog
Product Adoption School
Product Adoption School...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Team - Backlog - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pipelines - jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox (1,550) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"For you - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"For you - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Lukas Kovalik - Time Off","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lukas Kovalik - Time Off","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Product Growth Platform | Userpilot","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Product Growth Platform | Userpilot","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Userpilot","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Platform","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Solutions","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Solutions","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pricing","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pricing","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Integrations","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Integrations","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Resources","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Resources","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customers","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customers","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Free Trial","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Free Trial","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Log in","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Log in","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Get a Demo","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Get a Demo","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Drive Product Growth with","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Drive Product Growth with","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Insights.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Engagement.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Feedback.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Leverage user insights & in-app engagement to drive adoption, retention, and revenue.","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Enter your email address","depth":14,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Get a Demo","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"coming soon Userpilot AI","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"coming soon","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot AI","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"In-app Engagement","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-app Engagement","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Product Analytics","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Analytics","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"User Feedback","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Session Replay","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Session Replay","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Join 1,000+ Companies Accelerating Product Growth With Userpilot.","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Introducing Lia","depth":13,"bounds":{"left":0.08541667,"top":0.18555556,"width":0.06875,"height":0.02},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Userpilot’s AI Agent for Product Growth","depth":11,"bounds":{"left":0.058333334,"top":0.23444444,"width":0.55,"height":0.04},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot’s AI Agent for Product Growth","depth":12,"bounds":{"left":0.058333334,"top":0.23333333,"width":0.37361112,"height":0.04111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.","depth":12,"bounds":{"left":0.058333334,"top":0.29555556,"width":0.49166667,"height":0.05111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about Lia","depth":11,"bounds":{"left":0.058333334,"top":0.36444443,"width":0.14791666,"height":0.05111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about Lia","depth":12,"bounds":{"left":0.07638889,"top":0.37888888,"width":0.11180556,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"User Onboarding","depth":10,"bounds":{"left":0.035416666,"top":0.51555556,"width":0.24236111,"height":0.057777777},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Onboarding","depth":11,"bounds":{"left":0.035416666,"top":0.5144445,"width":0.24236111,"height":0.06},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Guide new users through your product and reduce time-to-value.","depth":11,"bounds":{"left":0.035416666,"top":0.6155556,"width":0.3986111,"height":0.093333334},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Help existing users discover new features contextually.","depth":11,"bounds":{"left":0.035416666,"top":0.66555554,"width":0.41041666,"height":0.14222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See User Onboarding Solutions","depth":10,"bounds":{"left":0.035416666,"top":0.8466667,"width":0.20208333,"height":0.054444443},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See User Onboarding Solutions","depth":11,"bounds":{"left":0.05347222,"top":0.86333334,"width":0.16597222,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product Analytics","depth":10,"bounds":{"left":0.6166667,"top":0.9011111,"width":0.25208333,"height":0.057777777},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product Analytics","depth":11,"bounds":{"left":0.6166667,"top":0.9,"width":0.25208333,"height":0.06},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Understand user behavior across the product journey.","depth":11,"bounds":{"left":0.6166667,"top":1.0,"width":0.38333333,"height":-0.0011111498},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Generate custom reports to answer any product question.","depth":11,"bounds":{"left":0.6166667,"top":1.0,"width":0.38333333,"height":-0.051111102},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See Analytics Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See Analytics Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"User Feedback","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"User Feedback","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Capture and analyze user sentiment at scale.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Understand how your users really feel with contextual Microsurveys.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See User Feedback Tools","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See User Feedback Tools","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Session Replay","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Session Replay","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn how users interact with your product.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See Session Replay Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See Session Replay Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Userpilot for Mobile","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot for Mobile","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use mobile-first UI patterns.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Onboard users, run surveys, and track product metrics on native mobile devices.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore Mobile Features","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore Mobile Features","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Rally Your Whole Team Around Your Product Growth Goals.","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Rally Your Whole Team Around Your Product Growth Goals.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Start 14 Days Free Trial","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start 14 Days Free Trial","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"No credit card required","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Kontentino improved New User Activation Rate by 10% in 1 month","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Kontentino improved New User Activation Rate by 10% in 1 month","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Integrate Userpilot with your favorite tech stack","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Integrate Userpilot with your favorite tech stack","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn More","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn More","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Unlock the Power of Product-Led Growth","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Unlock the Power of Product-Led Growth","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Best practices to help you","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"activate more users, increase user engagement","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"drive more product growth.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Userpilot Blog Learn about product growth, good UX and the latest trends in product management.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Userpilot Blog","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Userpilot Blog","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn about product growth, good UX and the latest trends in product management.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Read","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Read","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Upcoming Webinars","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upcoming Webinars","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upcoming live webinars, on-demand videos and webcasts.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Watch","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Watch","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Product Drive Conference","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product Drive Conference","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Learn from industry leaders and stay up-to-date on the latest trends in product growth.","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Connect","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Connect","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Take Your Product Experience to the Next Level","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Get a Demo","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Get a Demo","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Product","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Analytics","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Analytics","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Engagement","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Engagement","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Feedback","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Feedback","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Company","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Company","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Events","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Events","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Careers","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Careers","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customers","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customers","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Contact Us","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Contact Us","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"About Us","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"About Us","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Use Cases","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use Cases","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"User Onboarding","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"User Onboarding","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Adoption","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Adoption","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Customer Retention","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer Retention","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Led Growth","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Led Growth","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"In-App Support","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"In-App Support","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Roles","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Roles","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Growth","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Growth","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Marketing","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Marketing","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Management","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Management","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"UX Design","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"UX Design","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Resources","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resources","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Blog","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Blog","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Product Adoption School","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Product Adoption School","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
6319811850086158019
|
9011090310846713154
|
visual_change
|
accessibility
|
NULL
|
Platform Team - Backlog - Jira
Service-Desk - Queu Platform Team - Backlog - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Pipelines - jiminny/app
Feed — jiminny — Sentry
Inbox (1,550) - [EMAIL] - Jiminny Mail
For you - Confluence
For you - Confluence
Lukas Kovalik - Time Off
Lukas Kovalik - Time Off
Product Growth Platform | Userpilot
Product Growth Platform | Userpilot
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Userpilot
Platform
Platform
Solutions
Solutions
Pricing
Pricing
Integrations
Integrations
Resources
Resources
Customers
Customers
Free Trial
Free Trial
Log in
Log in
Get a Demo
Get a Demo
Drive Product Growth with
Drive Product Growth with
User Insights.
User Engagement.
User Feedback.
Leverage user insights & in-app engagement to drive adoption, retention, and revenue.
Enter your email address
Get a Demo
coming soon Userpilot AI
coming soon
Userpilot AI
In-app Engagement
In-app Engagement
Product Analytics
Product Analytics
User Feedback
User Feedback
Session Replay
Session Replay
Join 1,000+ Companies Accelerating Product Growth With Userpilot.
Introducing Lia
Userpilot’s AI Agent for Product Growth
Userpilot’s AI Agent for Product Growth
Your always-on growth teammate: understanding users, unlocking opportunities, and launching personalized campaigns at the perfect moment.
Learn more about Lia
Learn more about Lia
User Onboarding
User Onboarding
Guide new users through your product and reduce time-to-value.
Help existing users discover new features contextually.
See User Onboarding Solutions
See User Onboarding Solutions
Product Analytics
Product Analytics
Understand user behavior across the product journey.
Generate custom reports to answer any product question.
See Analytics Features
See Analytics Features
User Feedback
User Feedback
Capture and analyze user sentiment at scale.
Understand how your users really feel with contextual Microsurveys.
See User Feedback Tools
See User Feedback Tools
Session Replay
Session Replay
Learn how users interact with your product.
Identify bugs and fix confusing UI elements with a privacy-first Session Replay tool.
See Session Replay Features
See Session Replay Features
Userpilot for Mobile
Userpilot for Mobile
Use mobile-first UI patterns.
Onboard users, run surveys, and track product metrics on native mobile devices.
Explore Mobile Features
Explore Mobile Features
Rally Your Whole Team Around Your Product Growth Goals.
Rally Your Whole Team Around Your Product Growth Goals.
Start 14 Days Free Trial
Start 14 Days Free Trial
No credit card required
Kontentino improved New User Activation Rate by 10% in 1 month
Kontentino improved New User Activation Rate by 10% in 1 month
“Userpilot helped Kontentino improve their first and second run user experience. Kontentino saw a 10% increase in user activation as well as improvements in 1-week retention.”
Integrate Userpilot with your favorite tech stack
Integrate Userpilot with your favorite tech stack
Push data from Userpilot into other tools, and pull data from your CRM or analytics tools to create more powerful segments.
Learn More
Learn More
Unlock the Power of Product-Led Growth
Unlock the Power of Product-Led Growth
Best practices to help you
activate more users, increase user engagement
and
drive more product growth.
Userpilot Blog Learn about product growth, good UX and the latest trends in product management.
Userpilot Blog
Userpilot Blog
Learn about product growth, good UX and the latest trends in product management.
Read
Read
Upcoming Webinars Upcoming live webinars, on-demand videos and webcasts.
Upcoming Webinars
Upcoming Webinars
Upcoming live webinars, on-demand videos and webcasts.
Watch
Watch
Product Drive Conference Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Product Drive Conference
Product Drive Conference
Learn from industry leaders and stay up-to-date on the latest trends in product growth.
Connect
Connect
Take Your Product Experience to the Next Level
Get a Demo
Get a Demo
Product
Product
Product Analytics
Product Analytics
User Engagement
User Engagement
User Feedback
User Feedback
Company
Company
Events
Events
Careers
Careers
Customers
Customers
Contact Us
Contact Us
About Us
About Us
Use Cases
Use Cases
User Onboarding
User Onboarding
Product Adoption
Product Adoption
Customer Retention
Customer Retention
Product Led Growth
Product Led Growth
In-App Support
In-App Support
Roles
Roles
Product Growth
Product Growth
Product Marketing
Product Marketing
Product Management
Product Management
UX Design
UX Design
Resources
Resources
Blog
Blog
Product Adoption School
Product Adoption School...
|
19304
|
|
77665
|
1957
|
34
|
2026-04-24T09:53:37.588966+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-24/1777 /Users/lukas/.screenpipe/data/data/2026-04-24/1777024417588_m1.jpg...
|
PhpStorm
|
faVsco.js – ReportNotGenerated.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#12011 on JY-20157-AJ-rep Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportControllerTest
Run 'ReportControllerTest'
Debug 'ReportControllerTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Mail\Reports;
use Jiminny\Mail\Mailable;
class ReportNotGenerated extends Mailable
{
public function __construct(
private readonly string $reportName,
private readonly string $periodName,
private readonly string $reportsPageUrl,
private readonly string $mailSubject,
) {
}
public function build(): Mailable
{
$logoCDN = config('logos.cdn.header');
$fullLogoCDN = config('logos.cdn.footer');
$fromAddress = config('mail.from.address');
if (config('jiminny.deploy_region') === 'eu') {
$fromAddress = '[EMAIL]';
}
return $this
->from($fromAddress, config('mail.from.name'))
->view('emails.reports.report-not-generated', [
'reportName' => $this->reportName,
'periodName' => $this->periodName,
'reportsPageUrl' => $this->reportsPageUrl,
'isReport' => true,
'headerLogoCdn' => $logoCDN,
'footerLogoCdn' => $fullLogoCDN,
])
->subject($this->mailSubject);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\UserPilot;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Partner;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserPilotClient
{
private const API_ENDPOINT = 'https://api.userpilot.io/v1/';
private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';
private function createRequest(): PendingRequest
{
return Http::withHeaders([
'X-API-Version' => '2020-09-22',
'Authorization' => 'Token ' . config('services.userpilot.key'),
]);
}
public function track(User $user, string $event, array $payload = []): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [
'event_name' => $event,
'user_id' => $user->getUuid(),
'metadata' => $payload,
]);
}
public function upsertUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$companyMetadata = $this->getCompanyMetadata($user->getTeam());
$companyMetadata['id'] = $user->getTeam()->getUuid();
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [
'user_id' => $user->getUuid(),
'metadata' => [
'name' => $user->name,
'first_name' => $user->getFirstName(),
'position' => $user->job ? $user->job->name : null,
'email' => $user->getEmailAddress(),
'created_at' => $user->getCreatedAt()->unix(),
'is_admin' => $user->hasRole(User::ROLE_ADMIN),
'is_manager' => $user->hasRole(User::ROLE_MANAGER),
'is_owner' => $user->isTeamOwner(),
'is_insights' => $user->hasRole(User::ROLE_ANALYST),
'is_recorder' => $user->hasRole(User::ROLE_RECORDER),
'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),
'is_listener' => $user->hasRole(User::ROLE_LISTENER),
'license' => null,
'team' => $user->group ? $user->group->name : null,
'language' => $user->getLanguage(),
'email_sync' => $user->isSyncEmailEnabled(),
],
'company' => $companyMetadata,
]);
}
public function upsertCompany(Team $team): void
{
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [
'company_id' => $team->getUuid(),
'metadata' => $this->getCompanyMetadata($team),
]);
}
private function getCompanyMetadata(Team $team): array
{
return [
'created_at' => $team->getCreatedAt()->unix(),
'name' => $team->getName(),
'region' => config('jiminny.deploy_region'),
'crm' => $team->getCrmConfiguration()->getProviderName(),
'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),
'calendar' => $team->getCalendarProvider(),
'notification_provider' => $team->getNotificationProvider(),
'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),
'tier' => $team->getTier()?->getTitle(),
];
}
public function deleteUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'users', [
'users' => [$user->getUuid()],
]);
}
public function deleteCompany(Team $team): void
{
if ($this->shouldRequest($team) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'companies', [
'companies' => [$team->getUuid()],
]);
}
public function shouldRequest(Team $team): bool
{
return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#12011 on JY-20157-AJ-report-not-send-notification, menu","depth":5,"help_text":"Pull request #12011 exists for current branch JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"ReportControllerTest","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'ReportControllerTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'ReportControllerTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Mail\\Reports;\n\nuse Jiminny\\Mail\\Mailable;\n\nclass ReportNotGenerated extends Mailable\n{\n public function __construct(\n private readonly string $reportName,\n private readonly string $periodName,\n private readonly string $reportsPageUrl,\n private readonly string $mailSubject,\n ) {\n }\n\n public function build(): Mailable\n {\n $logoCDN = config('logos.cdn.header');\n $fullLogoCDN = config('logos.cdn.footer');\n\n $fromAddress = config('mail.from.address');\n if (config('jiminny.deploy_region') === 'eu') {\n $fromAddress = 'no-reply@jiminny.com';\n }\n\n return $this\n ->from($fromAddress, config('mail.from.name'))\n ->view('emails.reports.report-not-generated', [\n 'reportName' => $this->reportName,\n 'periodName' => $this->periodName,\n 'reportsPageUrl' => $this->reportsPageUrl,\n 'isReport' => true,\n 'headerLogoCdn' => $logoCDN,\n 'footerLogoCdn' => $fullLogoCDN,\n ])\n ->subject($this->mailSubject);\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Mail\\Reports;\n\nuse Jiminny\\Mail\\Mailable;\n\nclass ReportNotGenerated extends Mailable\n{\n public function __construct(\n private readonly string $reportName,\n private readonly string $periodName,\n private readonly string $reportsPageUrl,\n private readonly string $mailSubject,\n ) {\n }\n\n public function build(): Mailable\n {\n $logoCDN = config('logos.cdn.header');\n $fullLogoCDN = config('logos.cdn.footer');\n\n $fromAddress = config('mail.from.address');\n if (config('jiminny.deploy_region') === 'eu') {\n $fromAddress = 'no-reply@jiminny.com';\n }\n\n return $this\n ->from($fromAddress, config('mail.from.name'))\n ->view('emails.reports.report-not-generated', [\n 'reportName' => $this->reportName,\n 'periodName' => $this->periodName,\n 'reportsPageUrl' => $this->reportsPageUrl,\n 'isReport' => true,\n 'headerLogoCdn' => $logoCDN,\n 'footerLogoCdn' => $fullLogoCDN,\n ])\n ->subject($this->mailSubject);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"7","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Services\\UserPilot;\n\nuse Illuminate\\Http\\Client\\PendingRequest;\nuse Illuminate\\Support\\Facades\\Http;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Partner;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserPilotClient\n{\n private const API_ENDPOINT = 'https://api.userpilot.io/v1/';\n\n private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';\n\n private function createRequest(): PendingRequest\n {\n return Http::withHeaders([\n 'X-API-Version' => '2020-09-22',\n 'Authorization' => 'Token ' . config('services.userpilot.key'),\n ]);\n }\n\n public function track(User $user, string $event, array $payload = []): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [\n 'event_name' => $event,\n 'user_id' => $user->getUuid(),\n 'metadata' => $payload,\n ]);\n }\n\n public function upsertUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $companyMetadata = $this->getCompanyMetadata($user->getTeam());\n $companyMetadata['id'] = $user->getTeam()->getUuid();\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [\n 'user_id' => $user->getUuid(),\n 'metadata' => [\n 'name' => $user->name,\n 'first_name' => $user->getFirstName(),\n 'position' => $user->job ? $user->job->name : null,\n 'email' => $user->getEmailAddress(),\n 'created_at' => $user->getCreatedAt()->unix(),\n 'is_admin' => $user->hasRole(User::ROLE_ADMIN),\n 'is_manager' => $user->hasRole(User::ROLE_MANAGER),\n 'is_owner' => $user->isTeamOwner(),\n 'is_insights' => $user->hasRole(User::ROLE_ANALYST),\n 'is_recorder' => $user->hasRole(User::ROLE_RECORDER),\n 'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),\n 'is_listener' => $user->hasRole(User::ROLE_LISTENER),\n 'license' => null,\n 'team' => $user->group ? $user->group->name : null,\n 'language' => $user->getLanguage(),\n 'email_sync' => $user->isSyncEmailEnabled(),\n ],\n 'company' => $companyMetadata,\n ]);\n }\n\n public function upsertCompany(Team $team): void\n {\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [\n 'company_id' => $team->getUuid(),\n 'metadata' => $this->getCompanyMetadata($team),\n ]);\n }\n\n private function getCompanyMetadata(Team $team): array\n {\n return [\n 'created_at' => $team->getCreatedAt()->unix(),\n 'name' => $team->getName(),\n 'region' => config('jiminny.deploy_region'),\n 'crm' => $team->getCrmConfiguration()->getProviderName(),\n 'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),\n 'calendar' => $team->getCalendarProvider(),\n 'notification_provider' => $team->getNotificationProvider(),\n 'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),\n 'tier' => $team->getTier()?->getTitle(),\n ];\n }\n\n\n public function deleteUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'users', [\n 'users' => [$user->getUuid()],\n ]);\n }\n\n public function deleteCompany(Team $team): void\n {\n if ($this->shouldRequest($team) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'companies', [\n 'companies' => [$team->getUuid()],\n ]);\n }\n\n public function shouldRequest(Team $team): bool\n {\n return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;\n }\n\n}","depth":4,"value":"<?php\n\nnamespace Jiminny\\Services\\UserPilot;\n\nuse Illuminate\\Http\\Client\\PendingRequest;\nuse Illuminate\\Support\\Facades\\Http;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Partner;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserPilotClient\n{\n private const API_ENDPOINT = 'https://api.userpilot.io/v1/';\n\n private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';\n\n private function createRequest(): PendingRequest\n {\n return Http::withHeaders([\n 'X-API-Version' => '2020-09-22',\n 'Authorization' => 'Token ' . config('services.userpilot.key'),\n ]);\n }\n\n public function track(User $user, string $event, array $payload = []): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [\n 'event_name' => $event,\n 'user_id' => $user->getUuid(),\n 'metadata' => $payload,\n ]);\n }\n\n public function upsertUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $companyMetadata = $this->getCompanyMetadata($user->getTeam());\n $companyMetadata['id'] = $user->getTeam()->getUuid();\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [\n 'user_id' => $user->getUuid(),\n 'metadata' => [\n 'name' => $user->name,\n 'first_name' => $user->getFirstName(),\n 'position' => $user->job ? $user->job->name : null,\n 'email' => $user->getEmailAddress(),\n 'created_at' => $user->getCreatedAt()->unix(),\n 'is_admin' => $user->hasRole(User::ROLE_ADMIN),\n 'is_manager' => $user->hasRole(User::ROLE_MANAGER),\n 'is_owner' => $user->isTeamOwner(),\n 'is_insights' => $user->hasRole(User::ROLE_ANALYST),\n 'is_recorder' => $user->hasRole(User::ROLE_RECORDER),\n 'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),\n 'is_listener' => $user->hasRole(User::ROLE_LISTENER),\n 'license' => null,\n 'team' => $user->group ? $user->group->name : null,\n 'language' => $user->getLanguage(),\n 'email_sync' => $user->isSyncEmailEnabled(),\n ],\n 'company' => $companyMetadata,\n ]);\n }\n\n public function upsertCompany(Team $team): void\n {\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [\n 'company_id' => $team->getUuid(),\n 'metadata' => $this->getCompanyMetadata($team),\n ]);\n }\n\n private function getCompanyMetadata(Team $team): array\n {\n return [\n 'created_at' => $team->getCreatedAt()->unix(),\n 'name' => $team->getName(),\n 'region' => config('jiminny.deploy_region'),\n 'crm' => $team->getCrmConfiguration()->getProviderName(),\n 'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),\n 'calendar' => $team->getCalendarProvider(),\n 'notification_provider' => $team->getNotificationProvider(),\n 'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),\n 'tier' => $team->getTier()?->getTitle(),\n ];\n }\n\n\n public function deleteUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'users', [\n 'users' => [$user->getUuid()],\n ]);\n }\n\n public function deleteCompany(Team $team): void\n {\n if ($this->shouldRequest($team) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'companies', [\n 'companies' => [$team->getUuid()],\n ]);\n }\n\n public function shouldRequest(Team $team): bool\n {\n return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;\n }\n\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-2619394661958437459
|
8993391631608826732
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#12011 on JY-20157-AJ-rep Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportControllerTest
Run 'ReportControllerTest'
Debug 'ReportControllerTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Mail\Reports;
use Jiminny\Mail\Mailable;
class ReportNotGenerated extends Mailable
{
public function __construct(
private readonly string $reportName,
private readonly string $periodName,
private readonly string $reportsPageUrl,
private readonly string $mailSubject,
) {
}
public function build(): Mailable
{
$logoCDN = config('logos.cdn.header');
$fullLogoCDN = config('logos.cdn.footer');
$fromAddress = config('mail.from.address');
if (config('jiminny.deploy_region') === 'eu') {
$fromAddress = '[EMAIL]';
}
return $this
->from($fromAddress, config('mail.from.name'))
->view('emails.reports.report-not-generated', [
'reportName' => $this->reportName,
'periodName' => $this->periodName,
'reportsPageUrl' => $this->reportsPageUrl,
'isReport' => true,
'headerLogoCdn' => $logoCDN,
'footerLogoCdn' => $fullLogoCDN,
])
->subject($this->mailSubject);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\UserPilot;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Partner;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserPilotClient
{
private const API_ENDPOINT = 'https://api.userpilot.io/v1/';
private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';
private function createRequest(): PendingRequest
{
return Http::withHeaders([
'X-API-Version' => '2020-09-22',
'Authorization' => 'Token ' . config('services.userpilot.key'),
]);
}
public function track(User $user, string $event, array $payload = []): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [
'event_name' => $event,
'user_id' => $user->getUuid(),
'metadata' => $payload,
]);
}
public function upsertUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$companyMetadata = $this->getCompanyMetadata($user->getTeam());
$companyMetadata['id'] = $user->getTeam()->getUuid();
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [
'user_id' => $user->getUuid(),
'metadata' => [
'name' => $user->name,
'first_name' => $user->getFirstName(),
'position' => $user->job ? $user->job->name : null,
'email' => $user->getEmailAddress(),
'created_at' => $user->getCreatedAt()->unix(),
'is_admin' => $user->hasRole(User::ROLE_ADMIN),
'is_manager' => $user->hasRole(User::ROLE_MANAGER),
'is_owner' => $user->isTeamOwner(),
'is_insights' => $user->hasRole(User::ROLE_ANALYST),
'is_recorder' => $user->hasRole(User::ROLE_RECORDER),
'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),
'is_listener' => $user->hasRole(User::ROLE_LISTENER),
'license' => null,
'team' => $user->group ? $user->group->name : null,
'language' => $user->getLanguage(),
'email_sync' => $user->isSyncEmailEnabled(),
],
'company' => $companyMetadata,
]);
}
public function upsertCompany(Team $team): void
{
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [
'company_id' => $team->getUuid(),
'metadata' => $this->getCompanyMetadata($team),
]);
}
private function getCompanyMetadata(Team $team): array
{
return [
'created_at' => $team->getCreatedAt()->unix(),
'name' => $team->getName(),
'region' => config('jiminny.deploy_region'),
'crm' => $team->getCrmConfiguration()->getProviderName(),
'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),
'calendar' => $team->getCalendarProvider(),
'notification_provider' => $team->getNotificationProvider(),
'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),
'tier' => $team->getTier()?->getTitle(),
];
}
public function deleteUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'users', [
'users' => [$user->getUuid()],
]);
}
public function deleteCompany(Team $team): void
{
if ($this->shouldRequest($team) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'companies', [
'companies' => [$team->getUuid()],
]);
}
public function shouldRequest(Team $team): bool
{
return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
77664
|
|
77666
|
1958
|
38
|
2026-04-24T09:53:37.506474+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-24/1777 /Users/lukas/.screenpipe/data/data/2026-04-24/1777024417506_m2.jpg...
|
PhpStorm
|
faVsco.js – ReportNotGenerated.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#12011 on JY-20157-AJ-rep Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportControllerTest
Run 'ReportControllerTest'
Debug 'ReportControllerTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Mail\Reports;
use Jiminny\Mail\Mailable;
class ReportNotGenerated extends Mailable
{
public function __construct(
private readonly string $reportName,
private readonly string $periodName,
private readonly string $reportsPageUrl,
private readonly string $mailSubject,
) {
}
public function build(): Mailable
{
$logoCDN = config('logos.cdn.header');
$fullLogoCDN = config('logos.cdn.footer');
$fromAddress = config('mail.from.address');
if (config('jiminny.deploy_region') === 'eu') {
$fromAddress = '[EMAIL]';
}
return $this
->from($fromAddress, config('mail.from.name'))
->view('emails.reports.report-not-generated', [
'reportName' => $this->reportName,
'periodName' => $this->periodName,
'reportsPageUrl' => $this->reportsPageUrl,
'isReport' => true,
'headerLogoCdn' => $logoCDN,
'footerLogoCdn' => $fullLogoCDN,
])
->subject($this->mailSubject);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\UserPilot;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Partner;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserPilotClient
{
private const API_ENDPOINT = 'https://api.userpilot.io/v1/';
private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';
private function createRequest(): PendingRequest
{
return Http::withHeaders([
'X-API-Version' => '2020-09-22',
'Authorization' => 'Token ' . config('services.userpilot.key'),
]);
}
public function track(User $user, string $event, array $payload = []): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [
'event_name' => $event,
'user_id' => $user->getUuid(),
'metadata' => $payload,
]);
}
public function upsertUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$companyMetadata = $this->getCompanyMetadata($user->getTeam());
$companyMetadata['id'] = $user->getTeam()->getUuid();
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [
'user_id' => $user->getUuid(),
'metadata' => [
'name' => $user->name,
'first_name' => $user->getFirstName(),
'position' => $user->job ? $user->job->name : null,
'email' => $user->getEmailAddress(),
'created_at' => $user->getCreatedAt()->unix(),
'is_admin' => $user->hasRole(User::ROLE_ADMIN),
'is_manager' => $user->hasRole(User::ROLE_MANAGER),
'is_owner' => $user->isTeamOwner(),
'is_insights' => $user->hasRole(User::ROLE_ANALYST),
'is_recorder' => $user->hasRole(User::ROLE_RECORDER),
'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),
'is_listener' => $user->hasRole(User::ROLE_LISTENER),
'license' => null,
'team' => $user->group ? $user->group->name : null,
'language' => $user->getLanguage(),
'email_sync' => $user->isSyncEmailEnabled(),
],
'company' => $companyMetadata,
]);
}
public function upsertCompany(Team $team): void
{
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [
'company_id' => $team->getUuid(),
'metadata' => $this->getCompanyMetadata($team),
]);
}
private function getCompanyMetadata(Team $team): array
{
return [
'created_at' => $team->getCreatedAt()->unix(),
'name' => $team->getName(),
'region' => config('jiminny.deploy_region'),
'crm' => $team->getCrmConfiguration()->getProviderName(),
'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),
'calendar' => $team->getCalendarProvider(),
'notification_provider' => $team->getNotificationProvider(),
'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),
'tier' => $team->getTier()?->getTitle(),
];
}
public function deleteUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'users', [
'users' => [$user->getUuid()],
]);
}
public function deleteCompany(Team $team): void
{
if ($this->shouldRequest($team) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'companies', [
'companies' => [$team->getUuid()],
]);
}
public function shouldRequest(Team $team): bool
{
return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#12011 on JY-20157-AJ-report-not-send-notification, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.12134308,"height":0.025538707},"help_text":"Pull request #12011 exists for current branch JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8400931,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"ReportControllerTest","depth":6,"bounds":{"left":0.85538566,"top":0.019952115,"width":0.06017287,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'ReportControllerTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'ReportControllerTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Mail\\Reports;\n\nuse Jiminny\\Mail\\Mailable;\n\nclass ReportNotGenerated extends Mailable\n{\n public function __construct(\n private readonly string $reportName,\n private readonly string $periodName,\n private readonly string $reportsPageUrl,\n private readonly string $mailSubject,\n ) {\n }\n\n public function build(): Mailable\n {\n $logoCDN = config('logos.cdn.header');\n $fullLogoCDN = config('logos.cdn.footer');\n\n $fromAddress = config('mail.from.address');\n if (config('jiminny.deploy_region') === 'eu') {\n $fromAddress = 'no-reply@jiminny.com';\n }\n\n return $this\n ->from($fromAddress, config('mail.from.name'))\n ->view('emails.reports.report-not-generated', [\n 'reportName' => $this->reportName,\n 'periodName' => $this->periodName,\n 'reportsPageUrl' => $this->reportsPageUrl,\n 'isReport' => true,\n 'headerLogoCdn' => $logoCDN,\n 'footerLogoCdn' => $fullLogoCDN,\n ])\n ->subject($this->mailSubject);\n }\n}","depth":4,"bounds":{"left":0.18085106,"top":0.1963288,"width":0.24900267,"height":0.782921},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Mail\\Reports;\n\nuse Jiminny\\Mail\\Mailable;\n\nclass ReportNotGenerated extends Mailable\n{\n public function __construct(\n private readonly string $reportName,\n private readonly string $periodName,\n private readonly string $reportsPageUrl,\n private readonly string $mailSubject,\n ) {\n }\n\n public function build(): Mailable\n {\n $logoCDN = config('logos.cdn.header');\n $fullLogoCDN = config('logos.cdn.footer');\n\n $fromAddress = config('mail.from.address');\n if (config('jiminny.deploy_region') === 'eu') {\n $fromAddress = 'no-reply@jiminny.com';\n }\n\n return $this\n ->from($fromAddress, config('mail.from.name'))\n ->view('emails.reports.report-not-generated', [\n 'reportName' => $this->reportName,\n 'periodName' => $this->periodName,\n 'reportsPageUrl' => $this->reportsPageUrl,\n 'isReport' => true,\n 'headerLogoCdn' => $logoCDN,\n 'footerLogoCdn' => $fullLogoCDN,\n ])\n ->subject($this->mailSubject);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"7","depth":4,"bounds":{"left":0.67852396,"top":0.12529927,"width":0.0076462766,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6878325,"top":0.123703115,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.69514626,"top":0.123703115,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Services\\UserPilot;\n\nuse Illuminate\\Http\\Client\\PendingRequest;\nuse Illuminate\\Support\\Facades\\Http;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Partner;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserPilotClient\n{\n private const API_ENDPOINT = 'https://api.userpilot.io/v1/';\n\n private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';\n\n private function createRequest(): PendingRequest\n {\n return Http::withHeaders([\n 'X-API-Version' => '2020-09-22',\n 'Authorization' => 'Token ' . config('services.userpilot.key'),\n ]);\n }\n\n public function track(User $user, string $event, array $payload = []): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [\n 'event_name' => $event,\n 'user_id' => $user->getUuid(),\n 'metadata' => $payload,\n ]);\n }\n\n public function upsertUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $companyMetadata = $this->getCompanyMetadata($user->getTeam());\n $companyMetadata['id'] = $user->getTeam()->getUuid();\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [\n 'user_id' => $user->getUuid(),\n 'metadata' => [\n 'name' => $user->name,\n 'first_name' => $user->getFirstName(),\n 'position' => $user->job ? $user->job->name : null,\n 'email' => $user->getEmailAddress(),\n 'created_at' => $user->getCreatedAt()->unix(),\n 'is_admin' => $user->hasRole(User::ROLE_ADMIN),\n 'is_manager' => $user->hasRole(User::ROLE_MANAGER),\n 'is_owner' => $user->isTeamOwner(),\n 'is_insights' => $user->hasRole(User::ROLE_ANALYST),\n 'is_recorder' => $user->hasRole(User::ROLE_RECORDER),\n 'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),\n 'is_listener' => $user->hasRole(User::ROLE_LISTENER),\n 'license' => null,\n 'team' => $user->group ? $user->group->name : null,\n 'language' => $user->getLanguage(),\n 'email_sync' => $user->isSyncEmailEnabled(),\n ],\n 'company' => $companyMetadata,\n ]);\n }\n\n public function upsertCompany(Team $team): void\n {\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [\n 'company_id' => $team->getUuid(),\n 'metadata' => $this->getCompanyMetadata($team),\n ]);\n }\n\n private function getCompanyMetadata(Team $team): array\n {\n return [\n 'created_at' => $team->getCreatedAt()->unix(),\n 'name' => $team->getName(),\n 'region' => config('jiminny.deploy_region'),\n 'crm' => $team->getCrmConfiguration()->getProviderName(),\n 'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),\n 'calendar' => $team->getCalendarProvider(),\n 'notification_provider' => $team->getNotificationProvider(),\n 'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),\n 'tier' => $team->getTier()?->getTitle(),\n ];\n }\n\n\n public function deleteUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'users', [\n 'users' => [$user->getUuid()],\n ]);\n }\n\n public function deleteCompany(Team $team): void\n {\n if ($this->shouldRequest($team) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'companies', [\n 'companies' => [$team->getUuid()],\n ]);\n }\n\n public function shouldRequest(Team $team): bool\n {\n return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;\n }\n\n}","depth":4,"bounds":{"left":0.4418218,"top":0.0,"width":0.30784574,"height":1.0},"value":"<?php\n\nnamespace Jiminny\\Services\\UserPilot;\n\nuse Illuminate\\Http\\Client\\PendingRequest;\nuse Illuminate\\Support\\Facades\\Http;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Partner;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserPilotClient\n{\n private const API_ENDPOINT = 'https://api.userpilot.io/v1/';\n\n private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';\n\n private function createRequest(): PendingRequest\n {\n return Http::withHeaders([\n 'X-API-Version' => '2020-09-22',\n 'Authorization' => 'Token ' . config('services.userpilot.key'),\n ]);\n }\n\n public function track(User $user, string $event, array $payload = []): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [\n 'event_name' => $event,\n 'user_id' => $user->getUuid(),\n 'metadata' => $payload,\n ]);\n }\n\n public function upsertUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $companyMetadata = $this->getCompanyMetadata($user->getTeam());\n $companyMetadata['id'] = $user->getTeam()->getUuid();\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [\n 'user_id' => $user->getUuid(),\n 'metadata' => [\n 'name' => $user->name,\n 'first_name' => $user->getFirstName(),\n 'position' => $user->job ? $user->job->name : null,\n 'email' => $user->getEmailAddress(),\n 'created_at' => $user->getCreatedAt()->unix(),\n 'is_admin' => $user->hasRole(User::ROLE_ADMIN),\n 'is_manager' => $user->hasRole(User::ROLE_MANAGER),\n 'is_owner' => $user->isTeamOwner(),\n 'is_insights' => $user->hasRole(User::ROLE_ANALYST),\n 'is_recorder' => $user->hasRole(User::ROLE_RECORDER),\n 'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),\n 'is_listener' => $user->hasRole(User::ROLE_LISTENER),\n 'license' => null,\n 'team' => $user->group ? $user->group->name : null,\n 'language' => $user->getLanguage(),\n 'email_sync' => $user->isSyncEmailEnabled(),\n ],\n 'company' => $companyMetadata,\n ]);\n }\n\n public function upsertCompany(Team $team): void\n {\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [\n 'company_id' => $team->getUuid(),\n 'metadata' => $this->getCompanyMetadata($team),\n ]);\n }\n\n private function getCompanyMetadata(Team $team): array\n {\n return [\n 'created_at' => $team->getCreatedAt()->unix(),\n 'name' => $team->getName(),\n 'region' => config('jiminny.deploy_region'),\n 'crm' => $team->getCrmConfiguration()->getProviderName(),\n 'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),\n 'calendar' => $team->getCalendarProvider(),\n 'notification_provider' => $team->getNotificationProvider(),\n 'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),\n 'tier' => $team->getTier()?->getTitle(),\n ];\n }\n\n\n public function deleteUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'users', [\n 'users' => [$user->getUuid()],\n ]);\n }\n\n public function deleteCompany(Team $team): void\n {\n if ($this->shouldRequest($team) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'companies', [\n 'companies' => [$team->getUuid()],\n ]);\n }\n\n public function shouldRequest(Team $team): bool\n {\n return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;\n }\n\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-2619394661958437459
|
8993391631608826732
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#12011 on JY-20157-AJ-rep Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportControllerTest
Run 'ReportControllerTest'
Debug 'ReportControllerTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Mail\Reports;
use Jiminny\Mail\Mailable;
class ReportNotGenerated extends Mailable
{
public function __construct(
private readonly string $reportName,
private readonly string $periodName,
private readonly string $reportsPageUrl,
private readonly string $mailSubject,
) {
}
public function build(): Mailable
{
$logoCDN = config('logos.cdn.header');
$fullLogoCDN = config('logos.cdn.footer');
$fromAddress = config('mail.from.address');
if (config('jiminny.deploy_region') === 'eu') {
$fromAddress = '[EMAIL]';
}
return $this
->from($fromAddress, config('mail.from.name'))
->view('emails.reports.report-not-generated', [
'reportName' => $this->reportName,
'periodName' => $this->periodName,
'reportsPageUrl' => $this->reportsPageUrl,
'isReport' => true,
'headerLogoCdn' => $logoCDN,
'footerLogoCdn' => $fullLogoCDN,
])
->subject($this->mailSubject);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\UserPilot;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Partner;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserPilotClient
{
private const API_ENDPOINT = 'https://api.userpilot.io/v1/';
private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';
private function createRequest(): PendingRequest
{
return Http::withHeaders([
'X-API-Version' => '2020-09-22',
'Authorization' => 'Token ' . config('services.userpilot.key'),
]);
}
public function track(User $user, string $event, array $payload = []): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [
'event_name' => $event,
'user_id' => $user->getUuid(),
'metadata' => $payload,
]);
}
public function upsertUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$companyMetadata = $this->getCompanyMetadata($user->getTeam());
$companyMetadata['id'] = $user->getTeam()->getUuid();
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [
'user_id' => $user->getUuid(),
'metadata' => [
'name' => $user->name,
'first_name' => $user->getFirstName(),
'position' => $user->job ? $user->job->name : null,
'email' => $user->getEmailAddress(),
'created_at' => $user->getCreatedAt()->unix(),
'is_admin' => $user->hasRole(User::ROLE_ADMIN),
'is_manager' => $user->hasRole(User::ROLE_MANAGER),
'is_owner' => $user->isTeamOwner(),
'is_insights' => $user->hasRole(User::ROLE_ANALYST),
'is_recorder' => $user->hasRole(User::ROLE_RECORDER),
'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),
'is_listener' => $user->hasRole(User::ROLE_LISTENER),
'license' => null,
'team' => $user->group ? $user->group->name : null,
'language' => $user->getLanguage(),
'email_sync' => $user->isSyncEmailEnabled(),
],
'company' => $companyMetadata,
]);
}
public function upsertCompany(Team $team): void
{
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [
'company_id' => $team->getUuid(),
'metadata' => $this->getCompanyMetadata($team),
]);
}
private function getCompanyMetadata(Team $team): array
{
return [
'created_at' => $team->getCreatedAt()->unix(),
'name' => $team->getName(),
'region' => config('jiminny.deploy_region'),
'crm' => $team->getCrmConfiguration()->getProviderName(),
'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),
'calendar' => $team->getCalendarProvider(),
'notification_provider' => $team->getNotificationProvider(),
'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),
'tier' => $team->getTier()?->getTitle(),
];
}
public function deleteUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'users', [
'users' => [$user->getUuid()],
]);
}
public function deleteCompany(Team $team): void
{
if ($this->shouldRequest($team) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'companies', [
'companies' => [$team->getUuid()],
]);
}
public function shouldRequest(Team $team): bool
{
return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
77663
|
|
77667
|
1957
|
35
|
2026-04-24T09:53:38.623634+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-24/1777 /Users/lukas/.screenpipe/data/data/2026-04-24/1777024418623_m1.jpg...
|
PhpStorm
|
faVsco.js – ReportNotGenerated.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#12011 on JY-20157-AJ-rep Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportControllerTest
Run 'ReportControllerTest'
Debug 'ReportControllerTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Mail\Reports;
use Jiminny\Mail\Mailable;
class ReportNotGenerated extends Mailable
{
public function __construct(
private readonly string $reportName,
private readonly string $periodName,
private readonly string $reportsPageUrl,
private readonly string $mailSubject,
) {
}
public function build(): Mailable
{
$logoCDN = config('logos.cdn.header');
$fullLogoCDN = config('logos.cdn.footer');
$fromAddress = config('mail.from.address');
if (config('jiminny.deploy_region') === 'eu') {
$fromAddress = '[EMAIL]';
}
return $this
->from($fromAddress, config('mail.from.name'))
->view('emails.reports.report-not-generated', [
'reportName' => $this->reportName,
'periodName' => $this->periodName,
'reportsPageUrl' => $this->reportsPageUrl,
'isReport' => true,
'headerLogoCdn' => $logoCDN,
'footerLogoCdn' => $fullLogoCDN,
])
->subject($this->mailSubject);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\UserPilot;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Partner;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserPilotClient
{
private const API_ENDPOINT = 'https://api.userpilot.io/v1/';
private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';
private function createRequest(): PendingRequest
{
return Http::withHeaders([
'X-API-Version' => '2020-09-22',
'Authorization' => 'Token ' . config('services.userpilot.key'),
]);
}
public function track(User $user, string $event, array $payload = []): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [
'event_name' => $event,
'user_id' => $user->getUuid(),
'metadata' => $payload,
]);
}
public function upsertUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$companyMetadata = $this->getCompanyMetadata($user->getTeam());
$companyMetadata['id'] = $user->getTeam()->getUuid();
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [
'user_id' => $user->getUuid(),
'metadata' => [
'name' => $user->name,
'first_name' => $user->getFirstName(),
'position' => $user->job ? $user->job->name : null,
'email' => $user->getEmailAddress(),
'created_at' => $user->getCreatedAt()->unix(),
'is_admin' => $user->hasRole(User::ROLE_ADMIN),
'is_manager' => $user->hasRole(User::ROLE_MANAGER),
'is_owner' => $user->isTeamOwner(),
'is_insights' => $user->hasRole(User::ROLE_ANALYST),
'is_recorder' => $user->hasRole(User::ROLE_RECORDER),
'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),
'is_listener' => $user->hasRole(User::ROLE_LISTENER),
'license' => null,
'team' => $user->group ? $user->group->name : null,
'language' => $user->getLanguage(),
'email_sync' => $user->isSyncEmailEnabled(),
],
'company' => $companyMetadata,
]);
}
public function upsertCompany(Team $team): void
{
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [
'company_id' => $team->getUuid(),
'metadata' => $this->getCompanyMetadata($team),
]);
}
private function getCompanyMetadata(Team $team): array
{
return [
'created_at' => $team->getCreatedAt()->unix(),
'name' => $team->getName(),
'region' => config('jiminny.deploy_region'),
'crm' => $team->getCrmConfiguration()->getProviderName(),
'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),
'calendar' => $team->getCalendarProvider(),
'notification_provider' => $team->getNotificationProvider(),
'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),
'tier' => $team->getTier()?->getTitle(),
];
}
public function deleteUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'users', [
'users' => [$user->getUuid()],
]);
}
public function deleteCompany(Team $team): void
{
if ($this->shouldRequest($team) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'companies', [
'companies' => [$team->getUuid()],
]);
}
public function shouldRequest(Team $team): bool
{
return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#12011 on JY-20157-AJ-report-not-send-notification, menu","depth":5,"help_text":"Pull request #12011 exists for current branch JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"ReportControllerTest","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'ReportControllerTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'ReportControllerTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Mail\\Reports;\n\nuse Jiminny\\Mail\\Mailable;\n\nclass ReportNotGenerated extends Mailable\n{\n public function __construct(\n private readonly string $reportName,\n private readonly string $periodName,\n private readonly string $reportsPageUrl,\n private readonly string $mailSubject,\n ) {\n }\n\n public function build(): Mailable\n {\n $logoCDN = config('logos.cdn.header');\n $fullLogoCDN = config('logos.cdn.footer');\n\n $fromAddress = config('mail.from.address');\n if (config('jiminny.deploy_region') === 'eu') {\n $fromAddress = 'no-reply@jiminny.com';\n }\n\n return $this\n ->from($fromAddress, config('mail.from.name'))\n ->view('emails.reports.report-not-generated', [\n 'reportName' => $this->reportName,\n 'periodName' => $this->periodName,\n 'reportsPageUrl' => $this->reportsPageUrl,\n 'isReport' => true,\n 'headerLogoCdn' => $logoCDN,\n 'footerLogoCdn' => $fullLogoCDN,\n ])\n ->subject($this->mailSubject);\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Mail\\Reports;\n\nuse Jiminny\\Mail\\Mailable;\n\nclass ReportNotGenerated extends Mailable\n{\n public function __construct(\n private readonly string $reportName,\n private readonly string $periodName,\n private readonly string $reportsPageUrl,\n private readonly string $mailSubject,\n ) {\n }\n\n public function build(): Mailable\n {\n $logoCDN = config('logos.cdn.header');\n $fullLogoCDN = config('logos.cdn.footer');\n\n $fromAddress = config('mail.from.address');\n if (config('jiminny.deploy_region') === 'eu') {\n $fromAddress = 'no-reply@jiminny.com';\n }\n\n return $this\n ->from($fromAddress, config('mail.from.name'))\n ->view('emails.reports.report-not-generated', [\n 'reportName' => $this->reportName,\n 'periodName' => $this->periodName,\n 'reportsPageUrl' => $this->reportsPageUrl,\n 'isReport' => true,\n 'headerLogoCdn' => $logoCDN,\n 'footerLogoCdn' => $fullLogoCDN,\n ])\n ->subject($this->mailSubject);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"7","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Services\\UserPilot;\n\nuse Illuminate\\Http\\Client\\PendingRequest;\nuse Illuminate\\Support\\Facades\\Http;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Partner;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserPilotClient\n{\n private const API_ENDPOINT = 'https://api.userpilot.io/v1/';\n\n private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';\n\n private function createRequest(): PendingRequest\n {\n return Http::withHeaders([\n 'X-API-Version' => '2020-09-22',\n 'Authorization' => 'Token ' . config('services.userpilot.key'),\n ]);\n }\n\n public function track(User $user, string $event, array $payload = []): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [\n 'event_name' => $event,\n 'user_id' => $user->getUuid(),\n 'metadata' => $payload,\n ]);\n }\n\n public function upsertUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $companyMetadata = $this->getCompanyMetadata($user->getTeam());\n $companyMetadata['id'] = $user->getTeam()->getUuid();\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [\n 'user_id' => $user->getUuid(),\n 'metadata' => [\n 'name' => $user->name,\n 'first_name' => $user->getFirstName(),\n 'position' => $user->job ? $user->job->name : null,\n 'email' => $user->getEmailAddress(),\n 'created_at' => $user->getCreatedAt()->unix(),\n 'is_admin' => $user->hasRole(User::ROLE_ADMIN),\n 'is_manager' => $user->hasRole(User::ROLE_MANAGER),\n 'is_owner' => $user->isTeamOwner(),\n 'is_insights' => $user->hasRole(User::ROLE_ANALYST),\n 'is_recorder' => $user->hasRole(User::ROLE_RECORDER),\n 'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),\n 'is_listener' => $user->hasRole(User::ROLE_LISTENER),\n 'license' => null,\n 'team' => $user->group ? $user->group->name : null,\n 'language' => $user->getLanguage(),\n 'email_sync' => $user->isSyncEmailEnabled(),\n ],\n 'company' => $companyMetadata,\n ]);\n }\n\n public function upsertCompany(Team $team): void\n {\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [\n 'company_id' => $team->getUuid(),\n 'metadata' => $this->getCompanyMetadata($team),\n ]);\n }\n\n private function getCompanyMetadata(Team $team): array\n {\n return [\n 'created_at' => $team->getCreatedAt()->unix(),\n 'name' => $team->getName(),\n 'region' => config('jiminny.deploy_region'),\n 'crm' => $team->getCrmConfiguration()->getProviderName(),\n 'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),\n 'calendar' => $team->getCalendarProvider(),\n 'notification_provider' => $team->getNotificationProvider(),\n 'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),\n 'tier' => $team->getTier()?->getTitle(),\n ];\n }\n\n\n public function deleteUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'users', [\n 'users' => [$user->getUuid()],\n ]);\n }\n\n public function deleteCompany(Team $team): void\n {\n if ($this->shouldRequest($team) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'companies', [\n 'companies' => [$team->getUuid()],\n ]);\n }\n\n public function shouldRequest(Team $team): bool\n {\n return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;\n }\n\n}","depth":4,"value":"<?php\n\nnamespace Jiminny\\Services\\UserPilot;\n\nuse Illuminate\\Http\\Client\\PendingRequest;\nuse Illuminate\\Support\\Facades\\Http;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Partner;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserPilotClient\n{\n private const API_ENDPOINT = 'https://api.userpilot.io/v1/';\n\n private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';\n\n private function createRequest(): PendingRequest\n {\n return Http::withHeaders([\n 'X-API-Version' => '2020-09-22',\n 'Authorization' => 'Token ' . config('services.userpilot.key'),\n ]);\n }\n\n public function track(User $user, string $event, array $payload = []): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [\n 'event_name' => $event,\n 'user_id' => $user->getUuid(),\n 'metadata' => $payload,\n ]);\n }\n\n public function upsertUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $companyMetadata = $this->getCompanyMetadata($user->getTeam());\n $companyMetadata['id'] = $user->getTeam()->getUuid();\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [\n 'user_id' => $user->getUuid(),\n 'metadata' => [\n 'name' => $user->name,\n 'first_name' => $user->getFirstName(),\n 'position' => $user->job ? $user->job->name : null,\n 'email' => $user->getEmailAddress(),\n 'created_at' => $user->getCreatedAt()->unix(),\n 'is_admin' => $user->hasRole(User::ROLE_ADMIN),\n 'is_manager' => $user->hasRole(User::ROLE_MANAGER),\n 'is_owner' => $user->isTeamOwner(),\n 'is_insights' => $user->hasRole(User::ROLE_ANALYST),\n 'is_recorder' => $user->hasRole(User::ROLE_RECORDER),\n 'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),\n 'is_listener' => $user->hasRole(User::ROLE_LISTENER),\n 'license' => null,\n 'team' => $user->group ? $user->group->name : null,\n 'language' => $user->getLanguage(),\n 'email_sync' => $user->isSyncEmailEnabled(),\n ],\n 'company' => $companyMetadata,\n ]);\n }\n\n public function upsertCompany(Team $team): void\n {\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [\n 'company_id' => $team->getUuid(),\n 'metadata' => $this->getCompanyMetadata($team),\n ]);\n }\n\n private function getCompanyMetadata(Team $team): array\n {\n return [\n 'created_at' => $team->getCreatedAt()->unix(),\n 'name' => $team->getName(),\n 'region' => config('jiminny.deploy_region'),\n 'crm' => $team->getCrmConfiguration()->getProviderName(),\n 'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),\n 'calendar' => $team->getCalendarProvider(),\n 'notification_provider' => $team->getNotificationProvider(),\n 'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),\n 'tier' => $team->getTier()?->getTitle(),\n ];\n }\n\n\n public function deleteUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'users', [\n 'users' => [$user->getUuid()],\n ]);\n }\n\n public function deleteCompany(Team $team): void\n {\n if ($this->shouldRequest($team) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'companies', [\n 'companies' => [$team->getUuid()],\n ]);\n }\n\n public function shouldRequest(Team $team): bool\n {\n return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;\n }\n\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-2132150564896673439
|
8991137632780274540
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#12011 on JY-20157-AJ-rep Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportControllerTest
Run 'ReportControllerTest'
Debug 'ReportControllerTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Mail\Reports;
use Jiminny\Mail\Mailable;
class ReportNotGenerated extends Mailable
{
public function __construct(
private readonly string $reportName,
private readonly string $periodName,
private readonly string $reportsPageUrl,
private readonly string $mailSubject,
) {
}
public function build(): Mailable
{
$logoCDN = config('logos.cdn.header');
$fullLogoCDN = config('logos.cdn.footer');
$fromAddress = config('mail.from.address');
if (config('jiminny.deploy_region') === 'eu') {
$fromAddress = '[EMAIL]';
}
return $this
->from($fromAddress, config('mail.from.name'))
->view('emails.reports.report-not-generated', [
'reportName' => $this->reportName,
'periodName' => $this->periodName,
'reportsPageUrl' => $this->reportsPageUrl,
'isReport' => true,
'headerLogoCdn' => $logoCDN,
'footerLogoCdn' => $fullLogoCDN,
])
->subject($this->mailSubject);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\UserPilot;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Partner;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserPilotClient
{
private const API_ENDPOINT = 'https://api.userpilot.io/v1/';
private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';
private function createRequest(): PendingRequest
{
return Http::withHeaders([
'X-API-Version' => '2020-09-22',
'Authorization' => 'Token ' . config('services.userpilot.key'),
]);
}
public function track(User $user, string $event, array $payload = []): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [
'event_name' => $event,
'user_id' => $user->getUuid(),
'metadata' => $payload,
]);
}
public function upsertUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$companyMetadata = $this->getCompanyMetadata($user->getTeam());
$companyMetadata['id'] = $user->getTeam()->getUuid();
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [
'user_id' => $user->getUuid(),
'metadata' => [
'name' => $user->name,
'first_name' => $user->getFirstName(),
'position' => $user->job ? $user->job->name : null,
'email' => $user->getEmailAddress(),
'created_at' => $user->getCreatedAt()->unix(),
'is_admin' => $user->hasRole(User::ROLE_ADMIN),
'is_manager' => $user->hasRole(User::ROLE_MANAGER),
'is_owner' => $user->isTeamOwner(),
'is_insights' => $user->hasRole(User::ROLE_ANALYST),
'is_recorder' => $user->hasRole(User::ROLE_RECORDER),
'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),
'is_listener' => $user->hasRole(User::ROLE_LISTENER),
'license' => null,
'team' => $user->group ? $user->group->name : null,
'language' => $user->getLanguage(),
'email_sync' => $user->isSyncEmailEnabled(),
],
'company' => $companyMetadata,
]);
}
public function upsertCompany(Team $team): void
{
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [
'company_id' => $team->getUuid(),
'metadata' => $this->getCompanyMetadata($team),
]);
}
private function getCompanyMetadata(Team $team): array
{
return [
'created_at' => $team->getCreatedAt()->unix(),
'name' => $team->getName(),
'region' => config('jiminny.deploy_region'),
'crm' => $team->getCrmConfiguration()->getProviderName(),
'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),
'calendar' => $team->getCalendarProvider(),
'notification_provider' => $team->getNotificationProvider(),
'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),
'tier' => $team->getTier()?->getTitle(),
];
}
public function deleteUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'users', [
'users' => [$user->getUuid()],
]);
}
public function deleteCompany(Team $team): void
{
if ($this->shouldRequest($team) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'companies', [
'companies' => [$team->getUuid()],
]);
}
public function shouldRequest(Team $team): bool
{
return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
|
77668
|
1958
|
39
|
2026-04-24T09:53:38.623639+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-24/1777 /Users/lukas/.screenpipe/data/data/2026-04-24/1777024418623_m2.jpg...
|
PhpStorm
|
faVsco.js – ReportNotGenerated.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#12011 on JY-20157-AJ-rep Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportControllerTest
Run 'ReportControllerTest'
Debug 'ReportControllerTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Mail\Reports;
use Jiminny\Mail\Mailable;
class ReportNotGenerated extends Mailable
{
public function __construct(
private readonly string $reportName,
private readonly string $periodName,
private readonly string $reportsPageUrl,
private readonly string $mailSubject,
) {
}
public function build(): Mailable
{
$logoCDN = config('logos.cdn.header');
$fullLogoCDN = config('logos.cdn.footer');
$fromAddress = config('mail.from.address');
if (config('jiminny.deploy_region') === 'eu') {
$fromAddress = '[EMAIL]';
}
return $this
->from($fromAddress, config('mail.from.name'))
->view('emails.reports.report-not-generated', [
'reportName' => $this->reportName,
'periodName' => $this->periodName,
'reportsPageUrl' => $this->reportsPageUrl,
'isReport' => true,
'headerLogoCdn' => $logoCDN,
'footerLogoCdn' => $fullLogoCDN,
])
->subject($this->mailSubject);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\UserPilot;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Partner;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserPilotClient
{
private const API_ENDPOINT = 'https://api.userpilot.io/v1/';
private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';
private function createRequest(): PendingRequest
{
return Http::withHeaders([
'X-API-Version' => '2020-09-22',
'Authorization' => 'Token ' . config('services.userpilot.key'),
]);
}
public function track(User $user, string $event, array $payload = []): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [
'event_name' => $event,
'user_id' => $user->getUuid(),
'metadata' => $payload,
]);
}
public function upsertUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$companyMetadata = $this->getCompanyMetadata($user->getTeam());
$companyMetadata['id'] = $user->getTeam()->getUuid();
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [
'user_id' => $user->getUuid(),
'metadata' => [
'name' => $user->name,
'first_name' => $user->getFirstName(),
'position' => $user->job ? $user->job->name : null,
'email' => $user->getEmailAddress(),
'created_at' => $user->getCreatedAt()->unix(),
'is_admin' => $user->hasRole(User::ROLE_ADMIN),
'is_manager' => $user->hasRole(User::ROLE_MANAGER),
'is_owner' => $user->isTeamOwner(),
'is_insights' => $user->hasRole(User::ROLE_ANALYST),
'is_recorder' => $user->hasRole(User::ROLE_RECORDER),
'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),
'is_listener' => $user->hasRole(User::ROLE_LISTENER),
'license' => null,
'team' => $user->group ? $user->group->name : null,
'language' => $user->getLanguage(),
'email_sync' => $user->isSyncEmailEnabled(),
],
'company' => $companyMetadata,
]);
}
public function upsertCompany(Team $team): void
{
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [
'company_id' => $team->getUuid(),
'metadata' => $this->getCompanyMetadata($team),
]);
}
private function getCompanyMetadata(Team $team): array
{
return [
'created_at' => $team->getCreatedAt()->unix(),
'name' => $team->getName(),
'region' => config('jiminny.deploy_region'),
'crm' => $team->getCrmConfiguration()->getProviderName(),
'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),
'calendar' => $team->getCalendarProvider(),
'notification_provider' => $team->getNotificationProvider(),
'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),
'tier' => $team->getTier()?->getTitle(),
];
}
public function deleteUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'users', [
'users' => [$user->getUuid()],
]);
}
public function deleteCompany(Team $team): void
{
if ($this->shouldRequest($team) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'companies', [
'companies' => [$team->getUuid()],
]);
}
public function shouldRequest(Team $team): bool
{
return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#12011 on JY-20157-AJ-report-not-send-notification, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.12134308,"height":0.025538707},"help_text":"Pull request #12011 exists for current branch JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8400931,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"ReportControllerTest","depth":6,"bounds":{"left":0.85538566,"top":0.019952115,"width":0.06017287,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'ReportControllerTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'ReportControllerTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.39860374,"top":0.19952115,"width":0.007978723,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.40824467,"top":0.19792499,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.41555852,"top":0.19792499,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Mail\\Reports;\n\nuse Jiminny\\Mail\\Mailable;\n\nclass ReportNotGenerated extends Mailable\n{\n public function __construct(\n private readonly string $reportName,\n private readonly string $periodName,\n private readonly string $reportsPageUrl,\n private readonly string $mailSubject,\n ) {\n }\n\n public function build(): Mailable\n {\n $logoCDN = config('logos.cdn.header');\n $fullLogoCDN = config('logos.cdn.footer');\n\n $fromAddress = config('mail.from.address');\n if (config('jiminny.deploy_region') === 'eu') {\n $fromAddress = 'no-reply@jiminny.com';\n }\n\n return $this\n ->from($fromAddress, config('mail.from.name'))\n ->view('emails.reports.report-not-generated', [\n 'reportName' => $this->reportName,\n 'periodName' => $this->periodName,\n 'reportsPageUrl' => $this->reportsPageUrl,\n 'isReport' => true,\n 'headerLogoCdn' => $logoCDN,\n 'footerLogoCdn' => $fullLogoCDN,\n ])\n ->subject($this->mailSubject);\n }\n}","depth":4,"bounds":{"left":0.18085106,"top":0.1963288,"width":0.24135639,"height":0.782921},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Mail\\Reports;\n\nuse Jiminny\\Mail\\Mailable;\n\nclass ReportNotGenerated extends Mailable\n{\n public function __construct(\n private readonly string $reportName,\n private readonly string $periodName,\n private readonly string $reportsPageUrl,\n private readonly string $mailSubject,\n ) {\n }\n\n public function build(): Mailable\n {\n $logoCDN = config('logos.cdn.header');\n $fullLogoCDN = config('logos.cdn.footer');\n\n $fromAddress = config('mail.from.address');\n if (config('jiminny.deploy_region') === 'eu') {\n $fromAddress = 'no-reply@jiminny.com';\n }\n\n return $this\n ->from($fromAddress, config('mail.from.name'))\n ->view('emails.reports.report-not-generated', [\n 'reportName' => $this->reportName,\n 'periodName' => $this->periodName,\n 'reportsPageUrl' => $this->reportsPageUrl,\n 'isReport' => true,\n 'headerLogoCdn' => $logoCDN,\n 'footerLogoCdn' => $fullLogoCDN,\n ])\n ->subject($this->mailSubject);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"7","depth":4,"bounds":{"left":0.67852396,"top":0.12529927,"width":0.0076462766,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6878325,"top":0.123703115,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.69514626,"top":0.123703115,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Services\\UserPilot;\n\nuse Illuminate\\Http\\Client\\PendingRequest;\nuse Illuminate\\Support\\Facades\\Http;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Partner;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserPilotClient\n{\n private const API_ENDPOINT = 'https://api.userpilot.io/v1/';\n\n private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';\n\n private function createRequest(): PendingRequest\n {\n return Http::withHeaders([\n 'X-API-Version' => '2020-09-22',\n 'Authorization' => 'Token ' . config('services.userpilot.key'),\n ]);\n }\n\n public function track(User $user, string $event, array $payload = []): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [\n 'event_name' => $event,\n 'user_id' => $user->getUuid(),\n 'metadata' => $payload,\n ]);\n }\n\n public function upsertUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $companyMetadata = $this->getCompanyMetadata($user->getTeam());\n $companyMetadata['id'] = $user->getTeam()->getUuid();\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [\n 'user_id' => $user->getUuid(),\n 'metadata' => [\n 'name' => $user->name,\n 'first_name' => $user->getFirstName(),\n 'position' => $user->job ? $user->job->name : null,\n 'email' => $user->getEmailAddress(),\n 'created_at' => $user->getCreatedAt()->unix(),\n 'is_admin' => $user->hasRole(User::ROLE_ADMIN),\n 'is_manager' => $user->hasRole(User::ROLE_MANAGER),\n 'is_owner' => $user->isTeamOwner(),\n 'is_insights' => $user->hasRole(User::ROLE_ANALYST),\n 'is_recorder' => $user->hasRole(User::ROLE_RECORDER),\n 'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),\n 'is_listener' => $user->hasRole(User::ROLE_LISTENER),\n 'license' => null,\n 'team' => $user->group ? $user->group->name : null,\n 'language' => $user->getLanguage(),\n 'email_sync' => $user->isSyncEmailEnabled(),\n ],\n 'company' => $companyMetadata,\n ]);\n }\n\n public function upsertCompany(Team $team): void\n {\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [\n 'company_id' => $team->getUuid(),\n 'metadata' => $this->getCompanyMetadata($team),\n ]);\n }\n\n private function getCompanyMetadata(Team $team): array\n {\n return [\n 'created_at' => $team->getCreatedAt()->unix(),\n 'name' => $team->getName(),\n 'region' => config('jiminny.deploy_region'),\n 'crm' => $team->getCrmConfiguration()->getProviderName(),\n 'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),\n 'calendar' => $team->getCalendarProvider(),\n 'notification_provider' => $team->getNotificationProvider(),\n 'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),\n 'tier' => $team->getTier()?->getTitle(),\n ];\n }\n\n\n public function deleteUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'users', [\n 'users' => [$user->getUuid()],\n ]);\n }\n\n public function deleteCompany(Team $team): void\n {\n if ($this->shouldRequest($team) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'companies', [\n 'companies' => [$team->getUuid()],\n ]);\n }\n\n public function shouldRequest(Team $team): bool\n {\n return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;\n }\n\n}","depth":4,"bounds":{"left":0.4418218,"top":0.0,"width":0.30784574,"height":1.0},"value":"<?php\n\nnamespace Jiminny\\Services\\UserPilot;\n\nuse Illuminate\\Http\\Client\\PendingRequest;\nuse Illuminate\\Support\\Facades\\Http;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Partner;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\n\nclass UserPilotClient\n{\n private const API_ENDPOINT = 'https://api.userpilot.io/v1/';\n\n private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';\n\n private function createRequest(): PendingRequest\n {\n return Http::withHeaders([\n 'X-API-Version' => '2020-09-22',\n 'Authorization' => 'Token ' . config('services.userpilot.key'),\n ]);\n }\n\n public function track(User $user, string $event, array $payload = []): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [\n 'event_name' => $event,\n 'user_id' => $user->getUuid(),\n 'metadata' => $payload,\n ]);\n }\n\n public function upsertUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $companyMetadata = $this->getCompanyMetadata($user->getTeam());\n $companyMetadata['id'] = $user->getTeam()->getUuid();\n\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [\n 'user_id' => $user->getUuid(),\n 'metadata' => [\n 'name' => $user->name,\n 'first_name' => $user->getFirstName(),\n 'position' => $user->job ? $user->job->name : null,\n 'email' => $user->getEmailAddress(),\n 'created_at' => $user->getCreatedAt()->unix(),\n 'is_admin' => $user->hasRole(User::ROLE_ADMIN),\n 'is_manager' => $user->hasRole(User::ROLE_MANAGER),\n 'is_owner' => $user->isTeamOwner(),\n 'is_insights' => $user->hasRole(User::ROLE_ANALYST),\n 'is_recorder' => $user->hasRole(User::ROLE_RECORDER),\n 'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),\n 'is_listener' => $user->hasRole(User::ROLE_LISTENER),\n 'license' => null,\n 'team' => $user->group ? $user->group->name : null,\n 'language' => $user->getLanguage(),\n 'email_sync' => $user->isSyncEmailEnabled(),\n ],\n 'company' => $companyMetadata,\n ]);\n }\n\n public function upsertCompany(Team $team): void\n {\n $this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [\n 'company_id' => $team->getUuid(),\n 'metadata' => $this->getCompanyMetadata($team),\n ]);\n }\n\n private function getCompanyMetadata(Team $team): array\n {\n return [\n 'created_at' => $team->getCreatedAt()->unix(),\n 'name' => $team->getName(),\n 'region' => config('jiminny.deploy_region'),\n 'crm' => $team->getCrmConfiguration()->getProviderName(),\n 'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),\n 'calendar' => $team->getCalendarProvider(),\n 'notification_provider' => $team->getNotificationProvider(),\n 'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),\n 'tier' => $team->getTier()?->getTitle(),\n ];\n }\n\n\n public function deleteUser(User $user): void\n {\n if ($this->shouldRequest($user->getTeam()) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'users', [\n 'users' => [$user->getUuid()],\n ]);\n }\n\n public function deleteCompany(Team $team): void\n {\n if ($this->shouldRequest($team) === false) {\n return;\n }\n\n $this->createRequest()->delete(self::API_ENDPOINT . 'companies', [\n 'companies' => [$team->getUuid()],\n ]);\n }\n\n public function shouldRequest(Team $team): bool\n {\n return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;\n }\n\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-2132150564896673439
|
8991137632780274540
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#12011 on JY-20157-AJ-rep Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportControllerTest
Run 'ReportControllerTest'
Debug 'ReportControllerTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Mail\Reports;
use Jiminny\Mail\Mailable;
class ReportNotGenerated extends Mailable
{
public function __construct(
private readonly string $reportName,
private readonly string $periodName,
private readonly string $reportsPageUrl,
private readonly string $mailSubject,
) {
}
public function build(): Mailable
{
$logoCDN = config('logos.cdn.header');
$fullLogoCDN = config('logos.cdn.footer');
$fromAddress = config('mail.from.address');
if (config('jiminny.deploy_region') === 'eu') {
$fromAddress = '[EMAIL]';
}
return $this
->from($fromAddress, config('mail.from.name'))
->view('emails.reports.report-not-generated', [
'reportName' => $this->reportName,
'periodName' => $this->periodName,
'reportsPageUrl' => $this->reportsPageUrl,
'isReport' => true,
'headerLogoCdn' => $logoCDN,
'footerLogoCdn' => $fullLogoCDN,
])
->subject($this->mailSubject);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
7
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\UserPilot;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Partner;
use Jiminny\Models\Team;
use Jiminny\Models\User;
class UserPilotClient
{
private const API_ENDPOINT = 'https://api.userpilot.io/v1/';
private const ANALYTICS_ENDPOINT = 'https://analytex.userpilot.io/v1/';
private function createRequest(): PendingRequest
{
return Http::withHeaders([
'X-API-Version' => '2020-09-22',
'Authorization' => 'Token ' . config('services.userpilot.key'),
]);
}
public function track(User $user, string $event, array $payload = []): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'track', [
'event_name' => $event,
'user_id' => $user->getUuid(),
'metadata' => $payload,
]);
}
public function upsertUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$companyMetadata = $this->getCompanyMetadata($user->getTeam());
$companyMetadata['id'] = $user->getTeam()->getUuid();
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'identify', [
'user_id' => $user->getUuid(),
'metadata' => [
'name' => $user->name,
'first_name' => $user->getFirstName(),
'position' => $user->job ? $user->job->name : null,
'email' => $user->getEmailAddress(),
'created_at' => $user->getCreatedAt()->unix(),
'is_admin' => $user->hasRole(User::ROLE_ADMIN),
'is_manager' => $user->hasRole(User::ROLE_MANAGER),
'is_owner' => $user->isTeamOwner(),
'is_insights' => $user->hasRole(User::ROLE_ANALYST),
'is_recorder' => $user->hasRole(User::ROLE_RECORDER),
'is_jiminny_voice' => $user->hasRole(User::ROLE_RECORDER_AND_VOICE),
'is_listener' => $user->hasRole(User::ROLE_LISTENER),
'license' => null,
'team' => $user->group ? $user->group->name : null,
'language' => $user->getLanguage(),
'email_sync' => $user->isSyncEmailEnabled(),
],
'company' => $companyMetadata,
]);
}
public function upsertCompany(Team $team): void
{
$this->createRequest()->post(self::ANALYTICS_ENDPOINT . 'companies/identify', [
'company_id' => $team->getUuid(),
'metadata' => $this->getCompanyMetadata($team),
]);
}
private function getCompanyMetadata(Team $team): array
{
return [
'created_at' => $team->getCreatedAt()->unix(),
'name' => $team->getName(),
'region' => config('jiminny.deploy_region'),
'crm' => $team->getCrmConfiguration()->getProviderName(),
'crm_installed_app_version' => $team->getCrmConfiguration()->getInstalledAppVersion(),
'calendar' => $team->getCalendarProvider(),
'notification_provider' => $team->getNotificationProvider(),
'has_jiminny_voice' => $team->hasFeature(FeatureEnum::DIALER),
'tier' => $team->getTier()?->getTitle(),
];
}
public function deleteUser(User $user): void
{
if ($this->shouldRequest($user->getTeam()) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'users', [
'users' => [$user->getUuid()],
]);
}
public function deleteCompany(Team $team): void
{
if ($this->shouldRequest($team) === false) {
return;
}
$this->createRequest()->delete(self::API_ENDPOINT . 'companies', [
'companies' => [$team->getUuid()],
]);
}
public function shouldRequest(Team $team): bool
{
return config('services.userpilot.key') !== null && $team->getPartnerId() === Partner::PARTNER_DEFAULT;
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
|
72886
|
1778
|
15
|
2026-04-23T06:21:17.661331+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-23/1776 /Users/lukas/.screenpipe/data/data/2026-04-23/1776925277661_m1.jpg...
|
PhpStorm
|
faVsco.js – UserTransformer.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
Reposit
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
7/10
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20157-AJ-report-not-send-notification, menu","depth":5,"help_text":"Git Branch: JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"Reposit","depth":4,"value":"Reposit","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"7/10","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"13","depth":4,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","depth":4,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"36","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregator.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregatorInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatabaseActivities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatasourceInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivityInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Comments","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Forecast","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Jobs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"QueryBuilder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Services","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ClosingPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CreatedPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Criteria.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaNormalizer.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealContactService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsCriteriaBuilder.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepositoryInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsServiceRepositories.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PerformanceMonitor.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodOptionDecoratorInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodService.php, final class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskTypes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisk.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GroupDealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encoding, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encryption, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ES, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Faker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gecko, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gong, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Locks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Math, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Playlist, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Prophet, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Queue, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Router, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Saml2, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"SCIM, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Seeder, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sentry, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Serializer, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Settings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Slack, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Transcription, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"role_description":"text"}]...
|
-5534189712929839315
|
8983146191250327852
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
Reposit
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
7/10
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands...
|
72884
|
|
72895
|
1779
|
24
|
2026-04-23T06:21:38.439701+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-23/1776 /Users/lukas/.screenpipe/data/data/2026-04-23/1776925298439_m2.jpg...
|
PhpStorm
|
faVsco.js – UserTransformer.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
Reposit
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
6/10
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.25731382,"top":0.019952115,"width":0.03856383,"height":0.025538707},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20157-AJ-report-not-send-notification, menu","depth":5,"bounds":{"left":0.29587767,"top":0.019952115,"width":0.10139628,"height":0.025538707},"help_text":"Git Branch: JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.7972075,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"bounds":{"left":0.8125,"top":0.019952115,"width":0.10305851,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"bounds":{"left":0.35239363,"top":0.22905028,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.3650266,"top":0.22825219,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"Reposit","depth":4,"bounds":{"left":0.37599733,"top":0.22825219,"width":0.051861703,"height":0.015961692},"value":"Reposit","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.4368351,"top":0.22825219,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"bounds":{"left":0.44680852,"top":0.22825219,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"bounds":{"left":0.4554521,"top":0.22825219,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"bounds":{"left":0.46409574,"top":0.22825219,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6/10","depth":4,"bounds":{"left":0.47772607,"top":0.22745411,"width":0.025598405,"height":0.017557861},"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.50332445,"top":0.22665602,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"bounds":{"left":0.5119681,"top":0.22665602,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"bounds":{"left":0.5206117,"top":0.22665602,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"bounds":{"left":0.52925533,"top":0.22665602,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.54587764,"top":0.22665602,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"13","depth":4,"bounds":{"left":0.52327126,"top":0.25778133,"width":0.009640957,"height":0.015163607},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.5349069,"top":0.25778133,"width":0.007978723,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.54454786,"top":0.25618514,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.5518617,"top":0.25618514,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","depth":4,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"36","depth":4,"bounds":{"left":0.69980055,"top":0.15003991,"width":0.010305851,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.7117686,"top":0.14844373,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.7190825,"top":0.14844373,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.24335106,"top":0.047885075,"width":0.024268618,"height":0.024740623},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregator.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregatorInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatabaseActivities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatasourceInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivityInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Comments","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Forecast","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Jobs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"QueryBuilder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Services","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ClosingPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CreatedPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Criteria.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaNormalizer.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealContactService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsCriteriaBuilder.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepositoryInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsServiceRepositories.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PerformanceMonitor.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodOptionDecoratorInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodService.php, final class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskTypes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisk.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GroupDealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encoding, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encryption, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ES, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Faker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gecko, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gong, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Locks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Math, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Playlist, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Prophet, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Queue, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Router, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Saml2, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"SCIM, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Seeder, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sentry, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Serializer, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Settings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Slack, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Transcription, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"role_description":"text"}]...
|
3028690087852638560
|
8983146191250327852
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
Reposit
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
6/10
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder
Serializer, folder
Settings, folder
Sidekick, folder
Slack, folder
TeamInsights, folder
TimeMemoryMapper, folder
Transcription, folder
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands...
|
NULL
|
|
72882
|
1779
|
17
|
2026-04-23T06:21:11.632095+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-23/1776 /Users/lukas/.screenpipe/data/data/2026-04-23/1776925271632_m2.jpg...
|
PhpStorm
|
faVsco.js – UserTransformer.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
Reposit
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
1/10
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.25731382,"top":0.019952115,"width":0.03856383,"height":0.025538707},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20157-AJ-report-not-send-notification, menu","depth":5,"bounds":{"left":0.29587767,"top":0.019952115,"width":0.10139628,"height":0.025538707},"help_text":"Git Branch: JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.7972075,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"bounds":{"left":0.8125,"top":0.019952115,"width":0.10305851,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"bounds":{"left":0.35239363,"top":0.15482841,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.3650266,"top":0.15403032,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"Reposit","depth":4,"bounds":{"left":0.37599733,"top":0.15403032,"width":0.051861703,"height":0.015961692},"value":"Reposit","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.4368351,"top":0.15403032,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"bounds":{"left":0.44680852,"top":0.15403032,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"bounds":{"left":0.4554521,"top":0.15403032,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"bounds":{"left":0.46409574,"top":0.15403032,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1/10","depth":4,"bounds":{"left":0.47772607,"top":0.15323225,"width":0.025598405,"height":0.017557861},"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.50332445,"top":0.15243416,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"bounds":{"left":0.5119681,"top":0.15243416,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"bounds":{"left":0.5206117,"top":0.15243416,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"bounds":{"left":0.52925533,"top":0.15243416,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.6918218,"top":0.15243416,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"13","depth":4,"bounds":{"left":0.66921544,"top":0.18355946,"width":0.009640957,"height":0.015163607},"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.68085104,"top":0.18355946,"width":0.007978723,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.69049203,"top":0.1819633,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.6978058,"top":0.1819633,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","depth":4,"bounds":{"left":0.3700133,"top":0.18036711,"width":0.33477393,"height":0.8196329},"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"36","depth":4,"bounds":{"left":0.96210104,"top":0.10055866,"width":0.010305851,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.9740692,"top":0.09896249,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.98138297,"top":0.09896249,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.24335106,"top":0.047885075,"width":0.024268618,"height":0.024740623},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregator.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregatorInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatabaseActivities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatasourceInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivityInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Comments","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Forecast","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Jobs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"QueryBuilder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Services","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ClosingPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CreatedPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Criteria.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaNormalizer.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealContactService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsCriteriaBuilder.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepositoryInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsServiceRepositories.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PerformanceMonitor.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodOptionDecoratorInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodService.php, final class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskTypes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisk.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GroupDealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encoding, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encryption, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ES, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Faker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gecko, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gong, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Locks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Math, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Playlist, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Prophet, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Queue, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Router, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Saml2, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"SCIM, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Seeder, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Sentry, folder","depth":9,"role_description":"text"}]...
|
1427529211324442134
|
8983146156890589500
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
Reposit
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
1/10
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder
MobileSettings, folder
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage, folder
Playlist, folder
Prophet, folder
ProphetAi, folder
ProsperWorks, folder
Queue, folder
Router, folder
Saml2, folder
SCIM, folder
Seeder, folder
Sentry, folder...
|
72881
|
|
72894
|
1778
|
18
|
2026-04-23T06:21:35.188604+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-23/1776 /Users/lukas/.screenpipe/data/data/2026-04-23/1776925295188_m1.jpg...
|
PhpStorm
|
faVsco.js – UserTransformer.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
Reposit
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
6/10
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JY-20157-AJ-report-not-send-notification, menu","depth":5,"help_text":"Git Branch: JY-20157-AJ-report-not-send-notification","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"Reposit","depth":4,"value":"Reposit","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6/10","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"13","depth":4,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","depth":4,"value":"<?php\n\nnamespace Jiminny\\Http\\Transformers;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Component\\Sidekick\\SidekickService;\nuse Jiminny\\Exceptions\\ActivityProviderException;\nuse Jiminny\\Http\\Controllers\\Settings\\Users\\Utils\\UserSetting;\nuse Jiminny\\Models\\Activity\\Provider;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\JobTitle;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Notification\\Messengers\\MsTeams;\nuse Jiminny\\Services\\UserService;\nuse League\\Fractal\\Resource;\nuse League\\Fractal\\Resource\\Item;\nuse League\\Fractal\\TransformerAbstract;\n\nclass UserTransformer extends TransformerAbstract\n{\n protected array $availableIncludes = [\n 'team',\n 'group',\n 'job',\n 'roles',\n 'permissions',\n ];\n\n private Container $container;\n\n private bool $withSelfVisibility = false;\n\n public function __construct(?Container $container = null)\n {\n $this->container = $container ?? app();\n }\n\n public function withSelfVisibility(): self\n {\n $this->withSelfVisibility = true;\n\n return $this;\n }\n\n /**\n * @throws ActivityProviderException\n *\n * @return array<string, mixed>\n */\n public function transform(User $user): array\n {\n $attributes = [\n 'id' => $user->getUuid(),\n 'name' => $user->getName(),\n 'firstName' => $user->getFirstName(),\n 'photoUrl' => $user->getPhotoUrl(),\n 'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),\n 'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),\n // DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!\n 'crmRequired' => $user->crm_required,\n 'slackFollowUp' => $user->slack_follow_up,\n ];\n\n // DO NOT USE User::getId as it is not hydrated when fetched from ES!\n if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {\n $softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()\n && $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()\n ;\n\n $conferenceSidekickOpen = $user->getConferenceSidekickOpen();\n $softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();\n $conferenceSidekickPopupOverridden = false;\n $softphoneSidekickPopupOverridden = false;\n $hasSidekickEnabled = true;\n\n if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {\n $sidekickService = $this->getSidekickService();\n\n $sidekickData = $sidekickService->getSidekickSettingsForUser($user);\n\n $conferenceSidekickOpen = $sidekickData['conferenceSettings'];\n $softphoneSidekickOpen = $sidekickData['softphoneSettings'];\n $conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];\n $softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];\n $hasSidekickEnabled = $sidekickData['sidekickEnabled'];\n }\n\n $userService = $this->getUserService();\n $dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);\n $dataFormatCountryCode = $userService->getDateTimeCountryCode($user);\n\n // Attributes for the user only.\n $attributes += [\n 'conferenceJoinReminder' => $user->conference_join_reminder,\n 'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),\n 'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),\n 'softphoneInboundDestination' => $user->softphone_inbound_destination,\n 'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,\n 'softphoneNumber' => $user->getSoftPhoneNumber(),\n 'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),\n 'email' => $user->getEmailAddress(),\n 'secondaryEmail' => $user->getSecondaryEmailAddress(),\n 'phone' => $user->phone,\n 'secondaryPhone' => $user->secondary_phone,\n 'callerId' => $user->getCallerId(),\n 'countryCode' => $user->getCountryCode(),\n 'timezone' => $user->getTimezone()->getName(),\n 'language' => $user->getLanguage(),\n 'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),\n 'status' => $user->getStatus(),\n 'hash' => $user->generateHash(),\n 'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,\n 'notifyLiveCoaching' => $user->notify_live_coaching,\n 'activityLogReminder' => $user->activity_log_reminder,\n 'conferenceSidekickOpen' => $conferenceSidekickOpen,\n 'softphoneSidekickOpen' => $softphoneSidekickOpen,\n 'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,\n 'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,\n 'hasSidekickEnabled' => $hasSidekickEnabled,\n 'activityActionItems' => $user->activity_action_items,\n 'syncEmail' => $user->isSyncEmailEnabled(),\n 'syncConference' => $user->sync_conference,\n 'syncDialer' => $user->shouldSyncDialer(),\n 'needsToConfigurePhoneNumber' => $this->container\n ->get('onboarding_phone_decider')\n ->isOnboardable($user),\n 'shouldShowPhoneNumberField' => $this->container\n ->get('onboarding_phone_decider')\n ->shouldShowPhoneNumberField($user),\n UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,\n 'countryByTimezone' => $dataFormatCountryCode,\n 'conferenceSlug' => $user->getConferenceSlug(),\n 'conferenceRecordExternalOrganizerPreference' =>\n $userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),\n 'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,\n 'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),\n ];\n\n if ($user->softphone_debug) {\n $attributes += [\n 'debugSoftphone' => $user->softphone_debug, // Needed?\n ];\n }\n }\n\n if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {\n $socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);\n $state = $socialAccountMS !== null\n ? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)\n : null;\n\n $attributes['integrations']['office'] = [\n 'displayName' => 'Microsoft Teams',\n 'apiName' => 'microsoft-teams',\n 'types' => ['notification'],\n 'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,\n 'logo' => cdn('img/ms-teams-logo.svg'),\n 'installationStrategy' => 'oauth',\n ];\n }\n\n return $attributes;\n }\n\n public function includeTeam(User $user): Item\n {\n $team = $user->getTeam();\n\n return $this->item($team, $this->getTeamTransformer());\n }\n\n public function includeGroup(User $user): ?Item\n {\n $group = $user->getGroup();\n if ($group === null) {\n return null;\n }\n\n return $this->item($group, $this->getGroupTransformer());\n }\n\n public function includeJob(User $user): ?Item\n {\n $job = $user->getJobTitle();\n\n if (! $job instanceof JobTitle) {\n return null;\n }\n\n return $this->item($job, $this->getJobTitleTransformer());\n }\n\n public function includeRoles(User $user): Resource\\Collection\n {\n /** @var Collection<int, string> $roles */\n $roles = $user->roles()\n ->where('is_visible', true)\n ->pluck('name')\n ->toArray();\n\n return $this->collection($roles, $this->getRoleTransformer());\n }\n\n public function includePermissions(User $user): Resource\\Collection\n {\n $permissions = $user->allPermissions();\n\n return $this->collection($permissions, $this->getPermissionTransformer());\n }\n\n public function includeIntegrations(User $user): Item\n {\n return $this->item($user, $this->getIntegrationsTransformer());\n }\n\n private function getTeamTransformer(): TransformerAbstract\n {\n return $this->container->get(TeamTransformer::class);\n }\n\n private function getGroupTransformer(): GroupTransformer\n {\n return $this->container->get(GroupTransformer::class);\n }\n\n private function getIntegrationsTransformer(): IntegrationTransformer\n {\n return $this->container->get(IntegrationTransformer::class);\n }\n\n private function getPermissionTransformer(): PermissionTransformer\n {\n return $this->container->get(PermissionTransformer::class);\n }\n\n private function getRoleTransformer(): RoleTransformer\n {\n return $this->container->get(RoleTransformer::class);\n }\n\n private function getJobTitleTransformer(): JobTitleTransformer\n {\n return $this->container->get(JobTitleTransformer::class);\n }\n\n private function getSidekickService(): SidekickService\n {\n /** @var SidekickService */\n return $this->container->get(SidekickService::class);\n }\n\n private function getUserService(): UserService\n {\n /** @var UserService */\n return $this->container->get(UserService::class);\n }\n\n private function getAutomatedReportsRepository(): AutomatedReportsRepository\n {\n /** @var AutomatedReportsRepository */\n return $this->container->get(AutomatedReportsRepository::class);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"36","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Component\\DealInsights;\n\nuse Doctrine\\DBAL\\Connection;\nuse Generator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\DB;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealData;\nuse Jiminny\\Component\\DealInsights\\Forecast\\DealsFilter;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\QueryBuilder;\nuse Jiminny\\Component\\DealInsights\\QueryBuilder\\Visitor\\QueryBuilderVisitorInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Models;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\Utils\\UrlGeneratorInterface;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Traits\\RequiresUUID;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Eloquent;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass DealsRepository implements DealsRepositoryInterface\n{\n private Connection $connection;\n\n private ProviderRegistry $providerRegistry;\n\n /**\n * @var QueryBuilderVisitorInterface[]\n */\n private array $visitors = [];\n\n /**\n * @param QueryBuilderVisitorInterface[] $visitors\n */\n public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])\n {\n $this->connection = $connection;\n $this->providerRegistry = $crmProviderRegistry;\n\n foreach ($visitors as $visitor) {\n $this->visitors[$visitor->getIdentifier()] = $visitor;\n }\n }\n\n public function getDeals(CriteriaInterface $criteria): array\n {\n $context = $criteria->getContext();\n $team = $context->getTeam();\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n\n $this->visit($qb, $criteria);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getDeal(Team $team, int $id): array\n {\n $crmService = $this->getCrmService($team);\n\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);\n $qb = $this->getSearchSelectAndWhereClauses($qb);\n $qb->andWhere('opp.id = :id')->setParameter('id', $id);\n\n return $this->execute($team, $crmService, $qb);\n }\n\n public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')\n ->from('crm_fields', 'f')\n ->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')\n ->where('f.crm_configuration_id = :crm')\n ->andWhere('f.object_type = :type')\n ->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')\n ->orderBy('fd.object_id', 'ASC')\n ->addOrderBy('fd.updated_at', 'ASC')\n\n ->setParameter('type', Field::OBJECT_OPPORTUNITY)\n ->setParameter('crm', $crmId)\n ;\n\n if (! empty($crmFields)) {\n $fields = array_map(fn ($value): string => '\"' . $value . '\"', $crmFields);\n $qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');\n }\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAssociative();\n }\n\n public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array\n {\n $qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);\n\n $qb\n ->select('COALESCE(opp.currency_code, \"' . $defaultCurrency . '\") AS currency')\n ->addSelect('SUM(opp.value) as total')\n ->addSelect('count(*) as `count`')\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'))\n ->groupBy('currency')\n ;\n\n $this->visit($qb, $criteria);\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n public function getDealActivities(CriteriaInterface $criteria): array\n {\n $qb = Activity::with(['participants', 'user'])\n ->where('opportunity_id', $criteria->getOpportunityId())\n ->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())\n ->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())\n ->orderBy($criteria->getSortBy(), $criteria->getSortDirection())\n ;\n\n // Should we filter activities by criteria? It's intended to filter deals.\n\n return $qb->get()->all();\n }\n\n public function getStages(CriteriaInterface $criteria): array\n {\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('id', 'label', 'sequence')\n ->from('stages', 's')\n ->where('crm_configuration_id = :crm_configuration_id')\n ->andWhere('type = :type')\n ->orderBy('sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())\n ->setParameter('type', Stage::TYPE_OPPORTUNITY);\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $result[$row['id']] = [\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n public function getConfigurationStages(Configuration $configuration): Collection\n {\n return $configuration\n ->stages()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get();\n }\n\n public function getPipelineData(Configuration $crm): array\n {\n $qb = new QueryBuilder($this->connection);\n $provider = $crm->provider;\n\n $qb\n ->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')\n ->from('stages', 's')\n ->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')\n ->where('s.crm_configuration_id = :crm_configuration_id')\n ->andWhere('s.type = :type')\n ->orderBy('bps.business_process_id', 'ASC')\n ->addOrderBy('s.sequence', 'ASC')\n\n ->setParameter('crm_configuration_id', $crm->id)\n ->setParameter('type', Stage::TYPE_OPPORTUNITY)\n ;\n\n $result = [];\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];\n $result[$row['pipeline_id']][] = [\n 'value' => $value,\n 'label' => $row['label'],\n 'sequence' => $row['sequence'],\n ];\n }\n\n return $result;\n }\n\n private function createQueryBuilder(string $realm): QueryBuilder\n {\n return (new QueryBuilder($this->connection))\n ->setRealm($realm)\n ->from('opportunities', 'opp')\n ->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')\n ->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')\n ->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')\n ;\n }\n\n /**\n * Applies all applicable visitors and returns the IDs of the executed ones\n *\n * @return string[]\n */\n private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array\n {\n $queryVisitors = [];\n\n foreach ($this->visitors as $visitor) {\n if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {\n $visitor->visit($queryBuilder, $criteria);\n\n $queryVisitors[] = $visitor->getIdentifier();\n }\n }\n\n return $queryVisitors;\n }\n\n private function hydrateStages(array $deals): array\n {\n foreach ($this->fetchStages(array_keys($deals)) as $stage) {\n $oppId = (int) $stage['opportunity_id'];\n\n if (! isset($deals[$oppId])) {\n continue; // or throw??!\n }\n\n $deals[$oppId]['stages'][] = [\n 'id' => $stage['stage_id'],\n 'name' => $stage['label'],\n 'enteredAt' => $stage['created_at'],\n ];\n }\n\n return $deals;\n }\n\n /**\n * @param int[] $dealIds\n */\n private function fetchStages(array $dealIds): array\n {\n if (empty($dealIds)) {\n return [];\n }\n\n $qb = new QueryBuilder($this->connection);\n\n $qb\n ->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')\n ->from('opportunity_stages', 'os')\n ->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')\n ->where($qb->expr()->in('os.opportunity_id', $dealIds))\n ->orderBy('os.opportunity_id', 'ASC')\n ->addOrderBy('s.created_at', 'ASC')\n ;\n\n return $qb->executeQuery()->fetchAllAssociative();\n }\n\n private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array\n {\n $result = [];\n\n foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {\n $data = [\n 'uuid' => RequiresUUID::toNormal($row['uuid']),\n 'name' => $row['name'],\n 'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),\n 'account' => [\n 'name' => $row['acc_name'],\n 'url' => $crmService->generateProviderUrl(\n providerId: $row['acc_provider_id'],\n objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'\n ),\n ],\n 'owner' => null,\n 'rawValue' => [\n 'amount' => (float) $row['value'],\n 'currency' => $row['currency_code'],\n ],\n 'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),\n 'openDate' => $row['remotely_created_at'] ?? null,\n 'closeDate' => $row['close_date'] ?? null,\n 'stages' => [],\n 'currentPipelineId' => $row['pipeline_id'],\n 'currentStage' => [\n 'id' => $row['stage_id'],\n 'enteredAt' => $row['stage_updated_at'],\n ],\n 'currentStageUpdatedAt' => $row['stage_updated_at'],\n 'isClosed' => (bool) $row['is_closed'],\n 'isWon' => (bool) $row['is_won'],\n ];\n\n if (isset($row['owner_uuid'])) {\n $data['owner'] = [\n 'uuid' => RequiresUUID::toNormal($row['owner_uuid']),\n 'name' => $row['owner_name'],\n 'photoUrl' => $row['owner_photo'] === null\n ? null\n : client_cdn($row['owner_photo'], $team),\n 'id' => $row['owner_id'],\n 'job' => $row['owner_job'],\n ];\n }\n\n $result[(int) $row['opp_id']] = $data;\n }\n\n return $this->hydrateStages($result);\n }\n\n private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder\n {\n $qb = clone $queryBuilder;\n $qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');\n\n $qb\n ->select(...[\n 'opp.id as opp_id',\n 'opp.uuid',\n 'opp.name',\n 'opp.value',\n 'opp.currency_code',\n 'opp.close_date',\n 'opp.remotely_created_at',\n 'opp.is_closed',\n 'opp.is_won',\n ])\n ->addSelect(...[\n 'usr.uuid as owner_uuid',\n 'usr.name AS owner_name',\n 'usr.photo_path as owner_photo',\n 'usr.id AS owner_id',\n 'jt.name as owner_job',\n ])\n ->addSelect('opp.stage_id', 'opp.stage_updated_at')\n ->addSelect(...[\n 'acc.name AS acc_name',\n 'acc.is_internal as acc_is_internal',\n 'opp.stage_updated_at',\n 'acc.crm_provider_id AS acc_provider_id',\n 'opp.crm_provider_id AS opp_provider_id',\n ])\n ->addSelect('rt.business_process_id AS pipeline_id')\n\n ->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users\n ->andWhere($qb->expr()->isNull('opp.deleted_at'));\n\n return $qb;\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws SocialAccountTokenInvalidException\n */\n private function getCrmService(Team $team): ServiceInterface\n {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n $crmService->setConfiguration($team->crm);\n if ($crmService instanceof UrlGeneratorInterface) {\n $crmService->setCrmUrlGenerator($team->crm);\n }\n\n return $crmService;\n }\n\n /**\n *\n * @return Generator<DealData>\n */\n public function getForecastData(DealsFilter $filter): Generator\n {\n $opportunities = DB::query()\n ->select([\n 'o.value',\n 'o.close_date',\n 'o.currency_code',\n 'o.is_won',\n 'o.is_closed',\n 'o.probability',\n 'o.forecast_category',\n ])\n ->from('opportunities', 'o')\n ->join('users', 'users.id', '=', 'o.user_id')\n ->join('groups', 'groups.id', '=', 'users.group_id')\n ->where('users.team_id', $filter->getTeam()->getId())\n ->where('o.close_date', '>=', $filter->getStartDate())\n ->where('o.close_date', '<=', $filter->getEndDate())\n ->where('o.currency_code', $filter->getCurrency())\n ->where('o.deleted_at', '=', null)\n ;\n\n $userUuidList = $filter->getUserUuidList();\n if (! empty($userUuidList)) {\n $userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);\n\n $opportunities->whereIn('users.uuid', $userUuidList);\n }\n\n $groupUuidList = $filter->getGroupUuidList();\n if (! empty($groupUuidList)) {\n $groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);\n\n $opportunities->whereIn('groups.uuid', $groupUuidList);\n }\n\n foreach ($opportunities->cursor() as $row) {\n yield new DealData(\n (float) $row->value,\n $row->close_date,\n ! empty($row->is_won),\n ! empty($row->is_closed),\n $row->probability ?: 0,\n $row->forecast_category ?: '',\n );\n }\n }\n\n public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection\n {\n return $user->subscriptionSets()\n ->where(static function (Eloquent\\Builder $query): void {\n $query\n ->whereNull('expired_at')\n ->orWhere('expired_at', '>=', now());\n })\n ->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {\n $join\n ->on('subscription_set_id', '=', 'activity_subscription_sets.id');\n $join\n ->where('followable_type', Models\\Activity\\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)\n ->whereIn('followable_id', $opportunityIds);\n })\n ->pluck('followable_id');\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregator.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAggregatorInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatabaseActivities.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DatasourceInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivity.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"RelatedActivityInterface.php, interface","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Comments","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Forecast","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Jobs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"QueryBuilder","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Services","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ClosingPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CreatedPeriodOptionDecorator.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Criteria.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CriteriaNormalizer.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"CrmServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealContactService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsightsCriteriaBuilder.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsRepositoryInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealsServiceRepositories.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PerformanceMonitor.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodOptionDecoratorInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodService.php, final class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PeriodServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskTypes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisk.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksRepository.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksService.php, class","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRisksServiceInterface.php, interface","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GroupDealRiskType.php","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encoding, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Encryption, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"ES, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Faker, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gecko, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Gong, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Locks, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Math, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline, folder","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot, folder","depth":9,"role_description":"text"}]...
|
-5539052833710631969
|
8983146156890589500
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
JY-20157-AJ-report-not-se Project: faVsco.js, menu
JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
Reposit
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
6/10
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Code changed:
Hide
Sync Changes
Hide This Notification
13
2
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Transformers;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Collection;
use Jiminny\Component\Sidekick\SidekickService;
use Jiminny\Exceptions\ActivityProviderException;
use Jiminny\Http\Controllers\Settings\Users\Utils\UserSetting;
use Jiminny\Models\Activity\Provider;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\JobTitle;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Notification\Messengers\MsTeams;
use Jiminny\Services\UserService;
use League\Fractal\Resource;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'team',
'group',
'job',
'roles',
'permissions',
];
private Container $container;
private bool $withSelfVisibility = false;
public function __construct(?Container $container = null)
{
$this->container = $container ?? app();
}
public function withSelfVisibility(): self
{
$this->withSelfVisibility = true;
return $this;
}
/**
* @throws ActivityProviderException
*
* @return array<string, mixed>
*/
public function transform(User $user): array
{
$attributes = [
'id' => $user->getUuid(),
'name' => $user->getName(),
'firstName' => $user->getFirstName(),
'photoUrl' => $user->getPhotoUrl(),
'conferenceRecordPreference' => $user->checkConferenceRecordPreference(),
'conferenceRecordInternalPreference' => $user->checkConferenceRecordInternalPreference(),
// DO NOT USE User::isCrmRequired as it is not hydrated when fetched from ES!
'crmRequired' => $user->crm_required,
'slackFollowUp' => $user->slack_follow_up,
];
// DO NOT USE User::getId as it is not hydrated when fetched from ES!
if ($this->withSelfVisibility || (auth()->check() && auth()->user()->id === $user->id)) {
$softphoneHasVoiceCapability = $user->hasSoftphoneNumberCapabilities()
&& $user->getSoftphoneNumberCapabilities()->hasVoiceCapability()
;
$conferenceSidekickOpen = $user->getConferenceSidekickOpen();
$softphoneSidekickOpen = $user->getSoftphoneSidekickOpen();
$conferenceSidekickPopupOverridden = false;
$softphoneSidekickPopupOverridden = false;
$hasSidekickEnabled = true;
if ($user->getTeam()->hasFeature(FeatureEnum::SIDEKICK_SETTINGS)) {
$sidekickService = $this->getSidekickService();
$sidekickData = $sidekickService->getSidekickSettingsForUser($user);
$conferenceSidekickOpen = $sidekickData['conferenceSettings'];
$softphoneSidekickOpen = $sidekickData['softphoneSettings'];
$conferenceSidekickPopupOverridden = $sidekickData['conferenceSidekickPopupOverridden'];
$softphoneSidekickPopupOverridden = $sidekickData['softphoneSidekickPopupOverridden'];
$hasSidekickEnabled = $sidekickData['sidekickEnabled'];
}
$userService = $this->getUserService();
$dealInsightsPeriod = $userService->getDealInsightTimelinePeriod($user);
$dataFormatCountryCode = $userService->getDateTimeCountryCode($user);
// Attributes for the user only.
$attributes += [
'conferenceJoinReminder' => $user->conference_join_reminder,
'softphoneInboundRecordPreference' => $user->checkSoftphoneInboundRecordPreference(),
'softphoneOutboundRecordPreference' => $user->checkSoftphoneOutboundRecordPreference(),
'softphoneInboundDestination' => $user->softphone_inbound_destination,
'softphoneHasVoiceCapability' => $softphoneHasVoiceCapability,
'softphoneNumber' => $user->getSoftPhoneNumber(),
'formattedSoftphoneNumber' => $user->getFormattedSoftphoneNumberAttribute(),
'email' => $user->getEmailAddress(),
'secondaryEmail' => $user->getSecondaryEmailAddress(),
'phone' => $user->phone,
'secondaryPhone' => $user->secondary_phone,
'callerId' => $user->getCallerId(),
'countryCode' => $user->getCountryCode(),
'timezone' => $user->getTimezone()->getName(),
'language' => $user->getLanguage(),
'locales' => $this->container->get(UserRepository::class)->getUserLocales($user),
'status' => $user->getStatus(),
'hash' => $user->generateHash(),
'registrationDate' => $user->created_at ? $user->created_at->toIso8601String() : null,
'notifyLiveCoaching' => $user->notify_live_coaching,
'activityLogReminder' => $user->activity_log_reminder,
'conferenceSidekickOpen' => $conferenceSidekickOpen,
'softphoneSidekickOpen' => $softphoneSidekickOpen,
'conferenceSidekickPopupOverridden' => $conferenceSidekickPopupOverridden,
'softphoneSidekickPopupOverridden' => $softphoneSidekickPopupOverridden,
'hasSidekickEnabled' => $hasSidekickEnabled,
'activityActionItems' => $user->activity_action_items,
'syncEmail' => $user->isSyncEmailEnabled(),
'syncConference' => $user->sync_conference,
'syncDialer' => $user->shouldSyncDialer(),
'needsToConfigurePhoneNumber' => $this->container
->get('onboarding_phone_decider')
->isOnboardable($user),
'shouldShowPhoneNumberField' => $this->container
->get('onboarding_phone_decider')
->shouldShowPhoneNumberField($user),
UserSetting::DEAL_INSIGHTS_TIMELINE_PERIOD => $dealInsightsPeriod,
'countryByTimezone' => $dataFormatCountryCode,
'conferenceSlug' => $user->getConferenceSlug(),
'conferenceRecordExternalOrganizerPreference' =>
$userService->isConferenceRecordExternalOrganizerPreferenceEnabled($user),
'hasGeneratedAiReports' => $this->getAutomatedReportsRepository()->countUserReports($user) > 0,
'sendEmailWhenExportLinkIsOpened' => $userService->canSendEmailWhenExportLinkIsOpened($user),
];
if ($user->softphone_debug) {
$attributes += [
'debugSoftphone' => $user->softphone_debug, // Needed?
];
}
}
if ($user->getTeam()->getNotificationProvider() === Team::NOTIFICATION_PROVIDER_MSTEAMS) {
$socialAccountMS = $user->getSocialAccount(Team::CALENDAR_PROVIDER_OFFICE);
$state = $socialAccountMS !== null
? str_contains($socialAccountMS->auth_scope, MsTeams::SCOPE_CHAT_CREATE)
: null;
$attributes['integrations']['office'] = [
'displayName' => 'Microsoft Teams',
'apiName' => 'microsoft-teams',
'types' => ['notification'],
'state' => $state ? Provider::STATE_INSTALLED : Provider::STATE_NOT_INSTALLED,
'logo' => cdn('img/ms-teams-logo.svg'),
'installationStrategy' => 'oauth',
];
}
return $attributes;
}
public function includeTeam(User $user): Item
{
$team = $user->getTeam();
return $this->item($team, $this->getTeamTransformer());
}
public function includeGroup(User $user): ?Item
{
$group = $user->getGroup();
if ($group === null) {
return null;
}
return $this->item($group, $this->getGroupTransformer());
}
public function includeJob(User $user): ?Item
{
$job = $user->getJobTitle();
if (! $job instanceof JobTitle) {
return null;
}
return $this->item($job, $this->getJobTitleTransformer());
}
public function includeRoles(User $user): Resource\Collection
{
/** @var Collection<int, string> $roles */
$roles = $user->roles()
->where('is_visible', true)
->pluck('name')
->toArray();
return $this->collection($roles, $this->getRoleTransformer());
}
public function includePermissions(User $user): Resource\Collection
{
$permissions = $user->allPermissions();
return $this->collection($permissions, $this->getPermissionTransformer());
}
public function includeIntegrations(User $user): Item
{
return $this->item($user, $this->getIntegrationsTransformer());
}
private function getTeamTransformer(): TransformerAbstract
{
return $this->container->get(TeamTransformer::class);
}
private function getGroupTransformer(): GroupTransformer
{
return $this->container->get(GroupTransformer::class);
}
private function getIntegrationsTransformer(): IntegrationTransformer
{
return $this->container->get(IntegrationTransformer::class);
}
private function getPermissionTransformer(): PermissionTransformer
{
return $this->container->get(PermissionTransformer::class);
}
private function getRoleTransformer(): RoleTransformer
{
return $this->container->get(RoleTransformer::class);
}
private function getJobTitleTransformer(): JobTitleTransformer
{
return $this->container->get(JobTitleTransformer::class);
}
private function getSidekickService(): SidekickService
{
/** @var SidekickService */
return $this->container->get(SidekickService::class);
}
private function getUserService(): UserService
{
/** @var UserService */
return $this->container->get(UserService::class);
}
private function getAutomatedReportsRepository(): AutomatedReportsRepository
{
/** @var AutomatedReportsRepository */
return $this->container->get(AutomatedReportsRepository::class);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
36
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Component\DealInsights;
use Doctrine\DBAL\Connection;
use Generator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Jiminny\Component\DealInsights\Forecast\DealData;
use Jiminny\Component\DealInsights\Forecast\DealsFilter;
use Jiminny\Component\DealInsights\QueryBuilder\QueryBuilder;
use Jiminny\Component\DealInsights\QueryBuilder\Visitor\QueryBuilderVisitorInterface;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Models;
use Jiminny\Services\Crm\IntegrationApp\DTO\Utils\UrlGeneratorInterface;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Traits\RequiresUUID;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class DealsRepository implements DealsRepositoryInterface
{
private Connection $connection;
private ProviderRegistry $providerRegistry;
/**
* @var QueryBuilderVisitorInterface[]
*/
private array $visitors = [];
/**
* @param QueryBuilderVisitorInterface[] $visitors
*/
public function __construct(Connection $connection, ProviderRegistry $crmProviderRegistry, array $visitors = [])
{
$this->connection = $connection;
$this->providerRegistry = $crmProviderRegistry;
foreach ($visitors as $visitor) {
$this->visitors[$visitor->getIdentifier()] = $visitor;
}
}
public function getDeals(CriteriaInterface $criteria): array
{
$context = $criteria->getContext();
$team = $context->getTeam();
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$this->visit($qb, $criteria);
return $this->execute($team, $crmService, $qb);
}
public function getDeal(Team $team, int $id): array
{
$crmService = $this->getCrmService($team);
$qb = $this->createQueryBuilder(QueryBuilder::REALM_DEALS);
$qb = $this->getSearchSelectAndWhereClauses($qb);
$qb->andWhere('opp.id = :id')->setParameter('id', $id);
return $this->execute($team, $crmService, $qb);
}
public function getCrmFieldData(array $crmFields, int $crmId, array $opportunityIds = [])
{
$qb = new QueryBuilder($this->connection);
$qb
->select('f.id', 'f.crm_provider_id AS field_name', 'f.label', 'fd.object_id AS dealId', 'fd.value')
->from('crm_fields', 'f')
->join('f', 'crm_field_data', 'fd', 'fd.crm_field_id = f.id')
->where('f.crm_configuration_id = :crm')
->andWhere('f.object_type = :type')
->andWhere('fd.object_id IN (' . implode(',', $opportunityIds) . ')')
->orderBy('fd.object_id', 'ASC')
->addOrderBy('fd.updated_at', 'ASC')
->setParameter('type', Field::OBJECT_OPPORTUNITY)
->setParameter('crm', $crmId)
;
if (! empty($crmFields)) {
$fields = array_map(fn ($value): string => '"' . $value . '"', $crmFields);
$qb->andWhere('f.crm_provider_id IN (' . implode(',', $fields) . ')');
}
return $qb->executeQuery()->fetchAllAssociative();
}
public function getTotalsInDefaultCurrency(CriteriaInterface $criteria): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAssociative();
}
public function getTotals(CriteriaInterface $criteria, string $defaultCurrency): array
{
$qb = $this->createQueryBuilder(QueryBuilder::REALM_TOTALS);
$qb
->select('COALESCE(opp.currency_code, "' . $defaultCurrency . '") AS currency')
->addSelect('SUM(opp.value) as total')
->addSelect('count(*) as `count`')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not include deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'))
->groupBy('currency')
;
$this->visit($qb, $criteria);
return $qb->executeQuery()->fetchAllAssociative();
}
public function getDealActivities(CriteriaInterface $criteria): array
{
$qb = Activity::with(['participants', 'user'])
->where('opportunity_id', $criteria->getOpportunityId())
->whereDate('actual_start_time', '>=', $criteria->getPeriod()->getStartDate())
->whereDate('actual_start_time', '<=', $criteria->getPeriod()->getEndDate())
->orderBy($criteria->getSortBy(), $criteria->getSortDirection())
;
// Should we filter activities by criteria? It's intended to filter deals.
return $qb->get()->all();
}
public function getStages(CriteriaInterface $criteria): array
{
$qb = new QueryBuilder($this->connection);
$qb
->select('id', 'label', 'sequence')
->from('stages', 's')
->where('crm_configuration_id = :crm_configuration_id')
->andWhere('type = :type')
->orderBy('sequence', 'ASC')
->setParameter('crm_configuration_id', $criteria->getContext()->getTeam()->getCrmConfiguration()->getId())
->setParameter('type', Stage::TYPE_OPPORTUNITY);
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$result[$row['id']] = [
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
public function getConfigurationStages(Configuration $configuration): Collection
{
return $configuration
->stages()
->where('type', Stage::TYPE_OPPORTUNITY)
->get();
}
public function getPipelineData(Configuration $crm): array
{
$qb = new QueryBuilder($this->connection);
$provider = $crm->provider;
$qb
->select('s.label', 's.crm_provider_id', 's.sequence', 'bps.business_process_id AS pipeline_id')
->from('stages', 's')
->join('s', 'business_process_stages', 'bps', 's.id=bps.stage_id')
->where('s.crm_configuration_id = :crm_configuration_id')
->andWhere('s.type = :type')
->orderBy('bps.business_process_id', 'ASC')
->addOrderBy('s.sequence', 'ASC')
->setParameter('crm_configuration_id', $crm->id)
->setParameter('type', Stage::TYPE_OPPORTUNITY)
;
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$value = $provider === Configuration::PROVIDER_SALESFORCE ? $row['label'] : $row['crm_provider_id'];
$result[$row['pipeline_id']][] = [
'value' => $value,
'label' => $row['label'],
'sequence' => $row['sequence'],
];
}
return $result;
}
private function createQueryBuilder(string $realm): QueryBuilder
{
return (new QueryBuilder($this->connection))
->setRealm($realm)
->from('opportunities', 'opp')
->leftJoin('opp', 'record_types', 'rt', 'opp.record_type_id = rt.id')
->leftJoin('opp', 'users', 'usr', 'opp.user_id = usr.id')
->leftJoin('opp', 'accounts', 'acc', 'opp.account_id = acc.id')
;
}
/**
* Applies all applicable visitors and returns the IDs of the executed ones
*
* @return string[]
*/
private function visit(QueryBuilder $queryBuilder, CriteriaInterface $criteria): array
{
$queryVisitors = [];
foreach ($this->visitors as $visitor) {
if ($visitor->isSatisfiedBy($criteria, $queryBuilder->getRealm())) {
$visitor->visit($queryBuilder, $criteria);
$queryVisitors[] = $visitor->getIdentifier();
}
}
return $queryVisitors;
}
private function hydrateStages(array $deals): array
{
foreach ($this->fetchStages(array_keys($deals)) as $stage) {
$oppId = (int) $stage['opportunity_id'];
if (! isset($deals[$oppId])) {
continue; // or throw??!
}
$deals[$oppId]['stages'][] = [
'id' => $stage['stage_id'],
'name' => $stage['label'],
'enteredAt' => $stage['created_at'],
];
}
return $deals;
}
/**
* @param int[] $dealIds
*/
private function fetchStages(array $dealIds): array
{
if (empty($dealIds)) {
return [];
}
$qb = new QueryBuilder($this->connection);
$qb
->select('os.opportunity_id', 's.id AS stage_id', 's.label', 's.created_at')
->from('opportunity_stages', 'os')
->leftJoin('os', 'stages', 's', 'os.stage_id=s.id')
->where($qb->expr()->in('os.opportunity_id', $dealIds))
->orderBy('os.opportunity_id', 'ASC')
->addOrderBy('s.created_at', 'ASC')
;
return $qb->executeQuery()->fetchAllAssociative();
}
private function execute(Team $team, ServiceInterface $crmService, QueryBuilder $qb): array
{
$result = [];
foreach ($qb->executeQuery()->fetchAllAssociative() as $row) {
$data = [
'uuid' => RequiresUUID::toNormal($row['uuid']),
'name' => $row['name'],
'url' => $crmService->generateProviderUrl($row['opp_provider_id'], 'opportunity'),
'account' => [
'name' => $row['acc_name'],
'url' => $crmService->generateProviderUrl(
providerId: $row['acc_provider_id'],
objectType: $row['acc_is_internal'] ? 'internal-account' : 'account'
),
],
'owner' => null,
'rawValue' => [
'amount' => (float) $row['value'],
'currency' => $row['currency_code'],
],
'value' => formatOpportunityValue((float) $row['value'], $row['currency_code']),
'openDate' => $row['remotely_created_at'] ?? null,
'closeDate' => $row['close_date'] ?? null,
'stages' => [],
'currentPipelineId' => $row['pipeline_id'],
'currentStage' => [
'id' => $row['stage_id'],
'enteredAt' => $row['stage_updated_at'],
],
'currentStageUpdatedAt' => $row['stage_updated_at'],
'isClosed' => (bool) $row['is_closed'],
'isWon' => (bool) $row['is_won'],
];
if (isset($row['owner_uuid'])) {
$data['owner'] = [
'uuid' => RequiresUUID::toNormal($row['owner_uuid']),
'name' => $row['owner_name'],
'photoUrl' => $row['owner_photo'] === null
? null
: client_cdn($row['owner_photo'], $team),
'id' => $row['owner_id'],
'job' => $row['owner_job'],
];
}
$result[(int) $row['opp_id']] = $data;
}
return $this->hydrateStages($result);
}
private function getSearchSelectAndWhereClauses(QueryBuilder $queryBuilder): QueryBuilder
{
$qb = clone $queryBuilder;
$qb->leftJoin('usr', 'job_titles', 'jt', 'usr.job_title_id = jt.id');
$qb
->select(...[
'opp.id as opp_id',
'opp.uuid',
'opp.name',
'opp.value',
'opp.currency_code',
'opp.close_date',
'opp.remotely_created_at',
'opp.is_closed',
'opp.is_won',
])
->addSelect(...[
'usr.uuid as owner_uuid',
'usr.name AS owner_name',
'usr.photo_path as owner_photo',
'usr.id AS owner_id',
'jt.name as owner_job',
])
->addSelect('opp.stage_id', 'opp.stage_updated_at')
->addSelect(...[
'acc.name AS acc_name',
'acc.is_internal as acc_is_internal',
'opp.stage_updated_at',
'acc.crm_provider_id AS acc_provider_id',
'opp.crm_provider_id AS opp_provider_id',
])
->addSelect('rt.business_process_id AS pipeline_id')
->where($qb->expr()->isNotNull('opp.user_id')) // we should not display deals owned by external users
->andWhere($qb->expr()->isNull('opp.deleted_at'));
return $qb;
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws SocialAccountTokenInvalidException
*/
private function getCrmService(Team $team): ServiceInterface
{
$crmService = $this->providerRegistry->get($team->crm->provider);
$crmService->setConfiguration($team->crm);
if ($crmService instanceof UrlGeneratorInterface) {
$crmService->setCrmUrlGenerator($team->crm);
}
return $crmService;
}
/**
*
* @return Generator<DealData>
*/
public function getForecastData(DealsFilter $filter): Generator
{
$opportunities = DB::query()
->select([
'o.value',
'o.close_date',
'o.currency_code',
'o.is_won',
'o.is_closed',
'o.probability',
'o.forecast_category',
])
->from('opportunities', 'o')
->join('users', 'users.id', '=', 'o.user_id')
->join('groups', 'groups.id', '=', 'users.group_id')
->where('users.team_id', $filter->getTeam()->getId())
->where('o.close_date', '>=', $filter->getStartDate())
->where('o.close_date', '<=', $filter->getEndDate())
->where('o.currency_code', $filter->getCurrency())
->where('o.deleted_at', '=', null)
;
$userUuidList = $filter->getUserUuidList();
if (! empty($userUuidList)) {
$userUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $userUuidList);
$opportunities->whereIn('users.uuid', $userUuidList);
}
$groupUuidList = $filter->getGroupUuidList();
if (! empty($groupUuidList)) {
$groupUuidList = array_map(fn ($uuid) => RequiresUUID::toOptimized($uuid), $groupUuidList);
$opportunities->whereIn('groups.uuid', $groupUuidList);
}
foreach ($opportunities->cursor() as $row) {
yield new DealData(
(float) $row->value,
$row->close_date,
! empty($row->is_won),
! empty($row->is_closed),
$row->probability ?: 0,
$row->forecast_category ?: '',
);
}
}
public function getUserOpportunitySubscriptions(User $user, array $opportunityIds): Collection
{
return $user->subscriptionSets()
->where(static function (Eloquent\Builder $query): void {
$query
->whereNull('expired_at')
->orWhere('expired_at', '>=', now());
})
->join('activity_subscriptions', function (Builder $join) use ($opportunityIds) {
$join
->on('subscription_set_id', '=', 'activity_subscription_sets.id');
$join
->where('followable_type', Models\Activity\Subscription::FOLLOWABLE_TYPE_OPPORTUNITY)
->whereIn('followable_id', $opportunityIds);
})
->pluck('followable_id');
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
Activity
ActivityAggregator.php, class
ActivityAggregatorInterface.php, interface
DatabaseActivities.php, class
DatasourceInterface.php, interface
RelatedActivity.php, class
RelatedActivityInterface.php, interface
Commands
Comments
Forecast
Jobs
QueryBuilder
Services
ClosingPeriodOptionDecorator.php, class
CreatedPeriodOptionDecorator.php, class
Criteria.php, class
CriteriaInterface.php, interface
CriteriaNormalizer.php, class
CrmService.php, class
CrmServiceInterface.php, interface
DealContactService.php, class
DealInsightsCriteriaBuilder.php, class
DealService.php, class
DealServiceInterface.php, interface
DealsRepository.php, class
DealsRepositoryInterface.php, interface
DealsServiceRepositories.php, class
PerformanceMonitor.php, class
PeriodOptionDecoratorInterface.php, interface
PeriodService.php, final class
PeriodServiceInterface.php, interface
DealRisks
DealRiskTypes
DealRisk.php, class
DealRisksRepository.php, class
DealRisksService.php, class
DealRisksServiceInterface.php, interface
DealRiskType.php
GroupDealRiskType.php
ElasticSearch, folder
Eloquent, folder
Encoding, folder
Encryption, folder
ES, folder
Faker, folder
FeatureFlags, folder
FFMpeg, folder
FileSystem, folder
Gecko, folder
Gong, folder
GuzzleHttp, folder
KeyPoints, folder
Kiosk, folder
LanguageDetection
LiveFeed
Locks, folder
Math, folder
MediaPipeline, folder
MeetingBot, folder...
|
NULL
|
|
69209
|
1585
|
25
|
2026-04-22T07:40:19.448523+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-22/1776 /Users/lukas/.screenpipe/data/data/2026-04-22/1776843619448_m2.jpg...
|
PhpStorm
|
faVsco.js – AskJiminnyReportActivityService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AutomatedReportsServiceTest
Run 'AutomatedReportsServiceTest'
Debug 'AutomatedReportsServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
DATE_FILTER_KEYS
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
2/2
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Carbon\CarbonImmutable;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
?string $frequency = null,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
if ($frequency !== null) {
$dateRange = $this->calculateDateRangeForFrequency($frequency, $user);
if ($dateRange !== null) {
$requestParams[ActivityActualDate::PARAM_START_DATE] = $dateRange['start_date'];
$requestParams[ActivityActualDate::PARAM_END_DATE] = $dateRange['end_date'];
}
}
$criteria = Criteria::createFromRequest(
array_merge($requestParams, [
'limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT,
'page' => 1,
'sequence_number' => 1,
]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
/**
* @return array{start_date: string, end_date: string}|null
*/
private function calculateDateRangeForFrequency(string $frequency, User $user): ?array
{
$now = CarbonImmutable::now($user->getTimezone());
$range = match ($frequency) {
AutomatedReportsService::FREQUENCY_DAILY => [
$now->subDay()->startOfDay(),
$now->subDay()->endOfDay(),
],
AutomatedReportsService::FREQUENCY_WEEKLY => [
$now->subWeek()->startOfWeek(),
$now->subWeek()->endOfWeek(),
],
AutomatedReportsService::FREQUENCY_MONTHLY => [
$now->subMonthNoOverflow()->startOfMonth(),
$now->subMonthNoOverflow()->endOfMonth(),
],
AutomatedReportsService::FREQUENCY_QUARTERLY => [
$now->subQuarterNoOverflow()->startOfQuarter(),
$now->subQuarterNoOverflow()->endOfQuarter(),
],
default => null,
};
if ($range === null) {
return null;
}
return [
'start_date' => $range[0]->format('Y-m-d H:i:s'),
'end_date' => $range[1]->format('Y-m-d H:i:s'),
];
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
8
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Crm;
use Exception;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Database\Connection;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Jiminny\Component\Queue\Constants;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Repositories\ActivityRepository;
use Jiminny\Services\Crm\CrmActivityService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Throwable;
class MatchActivityCrmData extends Job implements ShouldQueue, ShouldBeUnique
{
use InteractsWithQueue;
use SerializesModels;
public int $tries = 3;
private int $activityId;
private ?Configuration $fromConfiguration;
private bool $remoteSearch;
public function __construct(
int $activityId,
?Configuration $fromConfiguration = null,
bool $remoteSearch = false,
) {
$this->activityId = $activityId;
$this->fromConfiguration = $fromConfiguration;
$this->remoteSearch = $remoteSearch;
$this->onQueue(Constants::QUEUE_ANALYTICS_LOW);
}
public function uniqueId(): string
{
$configId = $this->fromConfiguration?->getId() ?? 0;
$remote = $this->remoteSearch ? 'remote' : 'local';
return "$this->activityId:$configId:$remote";
}
public function timeout(): int
{
return 300; // 5 minutes max execution time
}
public function uniqueFor(): int
{
return $this->timeout() + 60; // timeout + 1 minute buffer
}
public function backoff(): array
{
return [30, 90, 180];
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws Exception|Throwable
*/
public function handle(
ActivityRepository $activityRepository,
CrmActivityService $crmActivityService,
Connection $connection,
): void {
$activity = $activityRepository->findById($this->activityId);
if ($activity === null) {
throw new InvalidArgumentException('[MatchActivityCrmData] Cannot find activity.');
}
try {
$connection->transaction(function () use ($activity, $crmActivityService, $activityRepository) {
Log::info('[MatchActivityCrmData] Starting CRM data matching', [
'activity' => $this->activityId,
'remote_search' => $this->remoteSearch,
'set_configuration' => $this->fromConfiguration?->getId(),
'old_state' => [
'lead_id' => $activity->getLead()?->getId(),
'contact_id' => $activity->getContact()?->getId(),
'account_id' => $activity->getAccount()?->getId(),
'opportunity_id' => $activity->getOpportunity()?->getId(),
'stage_id' => $activity->getStage()?->getId(),
],
]);
$this->resetCrmMappings($activity, $activityRepository);
$this->switchCrmConfigurationIfNeeded($activity);
$activity->refresh();
$crmActivityService->updateCrmData(
activity: $activity,
remoteSearch: $this->remoteSearch,
);
$hasMatch = $activity->getLead() !== null
|| $activity->getContact() !== null
|| $activity->getAccount() !== null
|| $activity->getOpportunity() !== null;
if ($hasMatch) {
Log::info('[MatchActivityCrmData] Successfully matched CRM data', [
'activity' => $this->activityId,
'remote_search' => $this->remoteSearch,
'lead_id' => $activity->getLead()?->getId(),
'contact_id' => $activity->getContact()?->getId(),
'account_id' => $activity->getAccount()?->getId(),
'opportunity_id' => $activity->getOpportunity()?->getId(),
'stage_id' => $activity->getStage()?->getId(),
]);
} else {
Log::info('[MatchActivityCrmData] No CRM match found', [
'activity' => $this->activityId,
'remote_search' => $this->remoteSearch,
]);
}
});
} catch (Throwable $e) {
Log::error('[MatchActivityCrmData] Failed to match CRM data', [
'activity' => $this->activityId,
'remote_search' => $this->remoteSearch,
'exception' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
throw $e;
}
}
public function failed(Throwable $exception): void
{
Log::error('[MatchActivityCrmData] Job permanently failed after all retries', [
'activity' => $this->activityId,
'remote_search' => $this->remoteSearch,
'from_configuration' => $this->fromConfiguration?->getId(),
'exception' => $exception->getMessage(),
'attempts' => $this->attempts(),
]);
}
private function resetCrmMappings(
Activity $activity,
ActivityRepository $activityRepository
): void {
$activity->update([
'lead_id' => null,
'contact_id' => null,
'account_id' => null,
'opportunity_id' => null,
'stage_id' => null,
]);
$participantsOldState = $activityRepository->getActivityParticipants($activity)
->map(function ($participant) {
return [
'id' => $participant->id,
'user_id' => $participant->user_id,
'contact_id' => $participant->contact_id,
'lead_id' => $participant->lead_id,
];
});
if ($participantsOldState->isNotEmpty()) {
Log::info('[MatchActivityCrmData] Participants old state', [
'activity' => $this->activityId,
'participants' => $participantsOldState->toArray(),
]);
}
$activity->participants()->update([
'user_id' => null,
'contact_id' => null,
'lead_id' => null,
]);
}
private function switchCrmConfigurationIfNeeded(Activity $activity): void
{
if ($this->fromConfiguration === null) {
return;
}
if ($activity->getCrm()?->getId() === $this->fromConfiguration->getId()) {
return;
}
Log::info('[MatchActivityCrmData] Switching CRM configuration', [
'activity' => $this->activityId,
'old_configuration' => $activity->getCrm()?->getId(),
'new_configuration' => $this->fromConfiguration->getId(),
]);
$activity->update([
'crm_configuration_id' => $this->fromConfiguration->getId(),
'crm_provider_id' => null,
]);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.25797874,"top":0.019952115,"width":0.03856383,"height":0.025538707},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.29654256,"top":0.019952115,"width":0.12732713,"height":0.025538707},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8218085,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AutomatedReportsServiceTest","depth":6,"bounds":{"left":0.83710104,"top":0.019952115,"width":0.078457445,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AutomatedReportsServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AutomatedReportsServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"bounds":{"left":0.35305852,"top":0.22905028,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.36569148,"top":0.22825219,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"DATE_FILTER_KEYS","depth":4,"bounds":{"left":0.37666222,"top":0.22825219,"width":0.056848403,"height":0.015961692},"value":"DATE_FILTER_KEYS","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.4424867,"top":0.22825219,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"bounds":{"left":0.4524601,"top":0.22825219,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"bounds":{"left":0.46110374,"top":0.22825219,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"bounds":{"left":0.46974733,"top":0.22825219,"width":0.00731383,"height":0.017557861},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2/2","depth":4,"bounds":{"left":0.48337767,"top":0.22745411,"width":0.025598405,"height":0.017557861},"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.50897604,"top":0.22665602,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"bounds":{"left":0.51761967,"top":0.22665602,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"bounds":{"left":0.5262633,"top":0.22665602,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"bounds":{"left":0.5349069,"top":0.22665602,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.7081117,"top":0.22665602,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.6881649,"top":0.25778133,"width":0.007978723,"height":0.015163607},"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.6981383,"top":0.25778133,"width":0.00731383,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.70711434,"top":0.25618514,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.7144282,"top":0.25618514,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Carbon\\CarbonImmutable;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ?string $frequency = null,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n if ($frequency !== null) {\n $dateRange = $this->calculateDateRangeForFrequency($frequency, $user);\n if ($dateRange !== null) {\n $requestParams[ActivityActualDate::PARAM_START_DATE] = $dateRange['start_date'];\n $requestParams[ActivityActualDate::PARAM_END_DATE] = $dateRange['end_date'];\n }\n }\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, [\n 'limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT,\n 'page' => 1,\n 'sequence_number' => 1,\n ]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n\n /**\n * @return array{start_date: string, end_date: string}|null\n */\n private function calculateDateRangeForFrequency(string $frequency, User $user): ?array\n {\n $now = CarbonImmutable::now($user->getTimezone());\n\n $range = match ($frequency) {\n AutomatedReportsService::FREQUENCY_DAILY => [\n $now->subDay()->startOfDay(),\n $now->subDay()->endOfDay(),\n ],\n AutomatedReportsService::FREQUENCY_WEEKLY => [\n $now->subWeek()->startOfWeek(),\n $now->subWeek()->endOfWeek(),\n ],\n AutomatedReportsService::FREQUENCY_MONTHLY => [\n $now->subMonthNoOverflow()->startOfMonth(),\n $now->subMonthNoOverflow()->endOfMonth(),\n ],\n AutomatedReportsService::FREQUENCY_QUARTERLY => [\n $now->subQuarterNoOverflow()->startOfQuarter(),\n $now->subQuarterNoOverflow()->endOfQuarter(),\n ],\n default => null,\n };\n\n if ($range === null) {\n return null;\n }\n\n return [\n 'start_date' => $range[0]->format('Y-m-d H:i:s'),\n 'end_date' => $range[1]->format('Y-m-d H:i:s'),\n ];\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Kiosk\\AutomatedReports;\n\nuse Carbon\\CarbonImmutable;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityActualDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\ActivityUpdatedDate;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinition\\DealInsights\\ClosingPeriodFilter;\nuse Jiminny\\Component\\ActivitySearch\\Service\\ActivitySearch;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\n\nclass AskJiminnyReportActivityService\n{\n private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;\n\n private const array DATE_FILTER_KEYS = [\n ActivityActualDate::PARAM_START_DATE,\n ActivityActualDate::PARAM_END_DATE,\n ActivityUpdatedDate::PARAM_UPDATED_FROM,\n ActivityUpdatedDate::PARAM_UPDATED_TO,\n ClosingPeriodFilter::KEY_START_DATE,\n ClosingPeriodFilter::KEY_END_DATE,\n ];\n\n public function __construct(\n private readonly ActivitySearch $activitySearch,\n private readonly ElasticActivityRepository $elasticRepository,\n private readonly LoggerInterface $logger,\n ) {\n }\n\n /**\n * Fetch activity IDs for a saved search, passing its filters as-is to Criteria.\n * Date filters stored on the saved search are excluded; if no other filters exist,\n * no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.\n *\n * @return string[] Activity IDs\n */\n public function getActivityIdsForSavedSearch(\n Search $savedSearch,\n User $user,\n ?string $frequency = null,\n ): array {\n $requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);\n\n if ($frequency !== null) {\n $dateRange = $this->calculateDateRangeForFrequency($frequency, $user);\n if ($dateRange !== null) {\n $requestParams[ActivityActualDate::PARAM_START_DATE] = $dateRange['start_date'];\n $requestParams[ActivityActualDate::PARAM_END_DATE] = $dateRange['end_date'];\n }\n }\n\n $criteria = Criteria::createFromRequest(\n array_merge($requestParams, [\n 'limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT,\n 'page' => 1,\n 'sequence_number' => 1,\n ]),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);\n\n $activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);\n\n $this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [\n 'saved_search_id' => $savedSearch->getId(),\n 'user_id' => $user->getId(),\n 'activity_count' => count($activityIds),\n ]);\n\n return $activityIds;\n }\n\n private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array\n {\n $params = [];\n $arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);\n\n foreach ($savedSearch->getFilters() as $filter) {\n $key = $filter->getFilterProperty();\n $value = $filter->getFilterValue();\n\n if (in_array($key, self::DATE_FILTER_KEYS, true)) {\n continue;\n }\n\n if (isset($params[$key])) {\n $params[$key][] = $value;\n } elseif (in_array($key, $arrayFilterKeys, true)) {\n $params[$key] = [$value];\n } else {\n $params[$key] = $value;\n }\n }\n\n return $params;\n }\n\n /**\n * @return array{start_date: string, end_date: string}|null\n */\n private function calculateDateRangeForFrequency(string $frequency, User $user): ?array\n {\n $now = CarbonImmutable::now($user->getTimezone());\n\n $range = match ($frequency) {\n AutomatedReportsService::FREQUENCY_DAILY => [\n $now->subDay()->startOfDay(),\n $now->subDay()->endOfDay(),\n ],\n AutomatedReportsService::FREQUENCY_WEEKLY => [\n $now->subWeek()->startOfWeek(),\n $now->subWeek()->endOfWeek(),\n ],\n AutomatedReportsService::FREQUENCY_MONTHLY => [\n $now->subMonthNoOverflow()->startOfMonth(),\n $now->subMonthNoOverflow()->endOfMonth(),\n ],\n AutomatedReportsService::FREQUENCY_QUARTERLY => [\n $now->subQuarterNoOverflow()->startOfQuarter(),\n $now->subQuarterNoOverflow()->endOfQuarter(),\n ],\n default => null,\n };\n\n if ($range === null) {\n return null;\n }\n\n return [\n 'start_date' => $range[0]->format('Y-m-d H:i:s'),\n 'end_date' => $range[1]->format('Y-m-d H:i:s'),\n ];\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"8","depth":4,"bounds":{"left":0.9644282,"top":0.10055866,"width":0.007978723,"height":0.015163607},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.9740692,"top":0.09896249,"width":0.00731383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.98138297,"top":0.09896249,"width":0.006981383,"height":0.018355945},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Crm;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Repositories\\ActivityRepository;\nuse Jiminny\\Services\\Crm\\CrmActivityService;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Throwable;\n\nclass MatchActivityCrmData extends Job implements ShouldQueue, ShouldBeUnique\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public int $tries = 3;\n\n private int $activityId;\n private ?Configuration $fromConfiguration;\n private bool $remoteSearch;\n\n public function __construct(\n int $activityId,\n ?Configuration $fromConfiguration = null,\n bool $remoteSearch = false,\n ) {\n $this->activityId = $activityId;\n $this->fromConfiguration = $fromConfiguration;\n $this->remoteSearch = $remoteSearch;\n\n $this->onQueue(Constants::QUEUE_ANALYTICS_LOW);\n }\n\n public function uniqueId(): string\n {\n $configId = $this->fromConfiguration?->getId() ?? 0;\n $remote = $this->remoteSearch ? 'remote' : 'local';\n\n return \"$this->activityId:$configId:$remote\";\n }\n\n public function timeout(): int\n {\n return 300; // 5 minutes max execution time\n }\n\n public function uniqueFor(): int\n {\n return $this->timeout() + 60; // timeout + 1 minute buffer\n }\n\n public function backoff(): array\n {\n return [30, 90, 180];\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws Exception|Throwable\n */\n public function handle(\n ActivityRepository $activityRepository,\n CrmActivityService $crmActivityService,\n Connection $connection,\n ): void {\n $activity = $activityRepository->findById($this->activityId);\n if ($activity === null) {\n throw new InvalidArgumentException('[MatchActivityCrmData] Cannot find activity.');\n }\n\n try {\n $connection->transaction(function () use ($activity, $crmActivityService, $activityRepository) {\n Log::info('[MatchActivityCrmData] Starting CRM data matching', [\n 'activity' => $this->activityId,\n 'remote_search' => $this->remoteSearch,\n 'set_configuration' => $this->fromConfiguration?->getId(),\n 'old_state' => [\n 'lead_id' => $activity->getLead()?->getId(),\n 'contact_id' => $activity->getContact()?->getId(),\n 'account_id' => $activity->getAccount()?->getId(),\n 'opportunity_id' => $activity->getOpportunity()?->getId(),\n 'stage_id' => $activity->getStage()?->getId(),\n ],\n ]);\n\n $this->resetCrmMappings($activity, $activityRepository);\n\n $this->switchCrmConfigurationIfNeeded($activity);\n\n $activity->refresh();\n\n $crmActivityService->updateCrmData(\n activity: $activity,\n remoteSearch: $this->remoteSearch,\n );\n\n $hasMatch = $activity->getLead() !== null\n || $activity->getContact() !== null\n || $activity->getAccount() !== null\n || $activity->getOpportunity() !== null;\n\n if ($hasMatch) {\n Log::info('[MatchActivityCrmData] Successfully matched CRM data', [\n 'activity' => $this->activityId,\n 'remote_search' => $this->remoteSearch,\n 'lead_id' => $activity->getLead()?->getId(),\n 'contact_id' => $activity->getContact()?->getId(),\n 'account_id' => $activity->getAccount()?->getId(),\n 'opportunity_id' => $activity->getOpportunity()?->getId(),\n 'stage_id' => $activity->getStage()?->getId(),\n ]);\n } else {\n Log::info('[MatchActivityCrmData] No CRM match found', [\n 'activity' => $this->activityId,\n 'remote_search' => $this->remoteSearch,\n ]);\n }\n });\n } catch (Throwable $e) {\n Log::error('[MatchActivityCrmData] Failed to match CRM data', [\n 'activity' => $this->activityId,\n 'remote_search' => $this->remoteSearch,\n 'exception' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n\n throw $e;\n }\n }\n\n public function failed(Throwable $exception): void\n {\n Log::error('[MatchActivityCrmData] Job permanently failed after all retries', [\n 'activity' => $this->activityId,\n 'remote_search' => $this->remoteSearch,\n 'from_configuration' => $this->fromConfiguration?->getId(),\n 'exception' => $exception->getMessage(),\n 'attempts' => $this->attempts(),\n ]);\n }\n\n private function resetCrmMappings(\n Activity $activity,\n ActivityRepository $activityRepository\n ): void {\n $activity->update([\n 'lead_id' => null,\n 'contact_id' => null,\n 'account_id' => null,\n 'opportunity_id' => null,\n 'stage_id' => null,\n ]);\n\n $participantsOldState = $activityRepository->getActivityParticipants($activity)\n ->map(function ($participant) {\n return [\n 'id' => $participant->id,\n 'user_id' => $participant->user_id,\n 'contact_id' => $participant->contact_id,\n 'lead_id' => $participant->lead_id,\n ];\n });\n\n if ($participantsOldState->isNotEmpty()) {\n Log::info('[MatchActivityCrmData] Participants old state', [\n 'activity' => $this->activityId,\n 'participants' => $participantsOldState->toArray(),\n ]);\n }\n\n $activity->participants()->update([\n 'user_id' => null,\n 'contact_id' => null,\n 'lead_id' => null,\n ]);\n }\n\n private function switchCrmConfigurationIfNeeded(Activity $activity): void\n {\n if ($this->fromConfiguration === null) {\n return;\n }\n\n if ($activity->getCrm()?->getId() === $this->fromConfiguration->getId()) {\n return;\n }\n\n Log::info('[MatchActivityCrmData] Switching CRM configuration', [\n 'activity' => $this->activityId,\n 'old_configuration' => $activity->getCrm()?->getId(),\n 'new_configuration' => $this->fromConfiguration->getId(),\n ]);\n\n $activity->update([\n 'crm_configuration_id' => $this->fromConfiguration->getId(),\n 'crm_provider_id' => null,\n ]);\n }\n}","depth":4,"bounds":{"left":0.7430186,"top":0.09736632,"width":0.24534574,"height":0.90263367},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Jobs\\Crm;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Illuminate\\Support\\Facades\\Log;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Jobs\\Job;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Repositories\\ActivityRepository;\nuse Jiminny\\Services\\Crm\\CrmActivityService;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse Psr\\Container\\NotFoundExceptionInterface;\nuse Throwable;\n\nclass MatchActivityCrmData extends Job implements ShouldQueue, ShouldBeUnique\n{\n use InteractsWithQueue;\n use SerializesModels;\n\n public int $tries = 3;\n\n private int $activityId;\n private ?Configuration $fromConfiguration;\n private bool $remoteSearch;\n\n public function __construct(\n int $activityId,\n ?Configuration $fromConfiguration = null,\n bool $remoteSearch = false,\n ) {\n $this->activityId = $activityId;\n $this->fromConfiguration = $fromConfiguration;\n $this->remoteSearch = $remoteSearch;\n\n $this->onQueue(Constants::QUEUE_ANALYTICS_LOW);\n }\n\n public function uniqueId(): string\n {\n $configId = $this->fromConfiguration?->getId() ?? 0;\n $remote = $this->remoteSearch ? 'remote' : 'local';\n\n return \"$this->activityId:$configId:$remote\";\n }\n\n public function timeout(): int\n {\n return 300; // 5 minutes max execution time\n }\n\n public function uniqueFor(): int\n {\n return $this->timeout() + 60; // timeout + 1 minute buffer\n }\n\n public function backoff(): array\n {\n return [30, 90, 180];\n }\n\n /**\n * @throws ContainerExceptionInterface\n * @throws NotFoundExceptionInterface\n * @throws Exception|Throwable\n */\n public function handle(\n ActivityRepository $activityRepository,\n CrmActivityService $crmActivityService,\n Connection $connection,\n ): void {\n $activity = $activityRepository->findById($this->activityId);\n if ($activity === null) {\n throw new InvalidArgumentException('[MatchActivityCrmData] Cannot find activity.');\n }\n\n try {\n $connection->transaction(function () use ($activity, $crmActivityService, $activityRepository) {\n Log::info('[MatchActivityCrmData] Starting CRM data matching', [\n 'activity' => $this->activityId,\n 'remote_search' => $this->remoteSearch,\n 'set_configuration' => $this->fromConfiguration?->getId(),\n 'old_state' => [\n 'lead_id' => $activity->getLead()?->getId(),\n 'contact_id' => $activity->getContact()?->getId(),\n 'account_id' => $activity->getAccount()?->getId(),\n 'opportunity_id' => $activity->getOpportunity()?->getId(),\n 'stage_id' => $activity->getStage()?->getId(),\n ],\n ]);\n\n $this->resetCrmMappings($activity, $activityRepository);\n\n $this->switchCrmConfigurationIfNeeded($activity);\n\n $activity->refresh();\n\n $crmActivityService->updateCrmData(\n activity: $activity,\n remoteSearch: $this->remoteSearch,\n );\n\n $hasMatch = $activity->getLead() !== null\n || $activity->getContact() !== null\n || $activity->getAccount() !== null\n || $activity->getOpportunity() !== null;\n\n if ($hasMatch) {\n Log::info('[MatchActivityCrmData] Successfully matched CRM data', [\n 'activity' => $this->activityId,\n 'remote_search' => $this->remoteSearch,\n 'lead_id' => $activity->getLead()?->getId(),\n 'contact_id' => $activity->getContact()?->getId(),\n 'account_id' => $activity->getAccount()?->getId(),\n 'opportunity_id' => $activity->getOpportunity()?->getId(),\n 'stage_id' => $activity->getStage()?->getId(),\n ]);\n } else {\n Log::info('[MatchActivityCrmData] No CRM match found', [\n 'activity' => $this->activityId,\n 'remote_search' => $this->remoteSearch,\n ]);\n }\n });\n } catch (Throwable $e) {\n Log::error('[MatchActivityCrmData] Failed to match CRM data', [\n 'activity' => $this->activityId,\n 'remote_search' => $this->remoteSearch,\n 'exception' => $e->getMessage(),\n 'trace' => $e->getTraceAsString(),\n ]);\n\n throw $e;\n }\n }\n\n public function failed(Throwable $exception): void\n {\n Log::error('[MatchActivityCrmData] Job permanently failed after all retries', [\n 'activity' => $this->activityId,\n 'remote_search' => $this->remoteSearch,\n 'from_configuration' => $this->fromConfiguration?->getId(),\n 'exception' => $exception->getMessage(),\n 'attempts' => $this->attempts(),\n ]);\n }\n\n private function resetCrmMappings(\n Activity $activity,\n ActivityRepository $activityRepository\n ): void {\n $activity->update([\n 'lead_id' => null,\n 'contact_id' => null,\n 'account_id' => null,\n 'opportunity_id' => null,\n 'stage_id' => null,\n ]);\n\n $participantsOldState = $activityRepository->getActivityParticipants($activity)\n ->map(function ($participant) {\n return [\n 'id' => $participant->id,\n 'user_id' => $participant->user_id,\n 'contact_id' => $participant->contact_id,\n 'lead_id' => $participant->lead_id,\n ];\n });\n\n if ($participantsOldState->isNotEmpty()) {\n Log::info('[MatchActivityCrmData] Participants old state', [\n 'activity' => $this->activityId,\n 'participants' => $participantsOldState->toArray(),\n ]);\n }\n\n $activity->participants()->update([\n 'user_id' => null,\n 'contact_id' => null,\n 'lead_id' => null,\n ]);\n }\n\n private function switchCrmConfigurationIfNeeded(Activity $activity): void\n {\n if ($this->fromConfiguration === null) {\n return;\n }\n\n if ($activity->getCrm()?->getId() === $this->fromConfiguration->getId()) {\n return;\n }\n\n Log::info('[MatchActivityCrmData] Switching CRM configuration', [\n 'activity' => $this->activityId,\n 'old_configuration' => $activity->getCrm()?->getId(),\n 'new_configuration' => $this->fromConfiguration->getId(),\n ]);\n\n $activity->update([\n 'crm_configuration_id' => $this->fromConfiguration->getId(),\n 'crm_provider_id' => null,\n ]);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.24401596,"top":0.047885075,"width":0.024268618,"height":0.024740623},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"bounds":{"left":0.25299203,"top":0.074221864,"width":0.045877658,"height":0.017557861},"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"bounds":{"left":0.25930852,"top":0.09177973,"width":0.023936171,"height":0.017557861},"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"bounds":{"left":0.25930852,"top":0.10933759,"width":0.022273935,"height":0.017557861},"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"bounds":{"left":0.25930852,"top":0.12689546,"width":0.022273935,"height":0.017557861},"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"bounds":{"left":0.25930852,"top":0.14445332,"width":0.026928192,"height":0.017557861},"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"bounds":{"left":0.25930852,"top":0.16201118,"width":0.024268618,"height":0.017557861},"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"bounds":{"left":0.25930852,"top":0.17956904,"width":0.026928192,"height":0.017557861},"role_description":"text"}]...
|
-1662539276846558595
|
8972300499759341876
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
AutomatedReportsServiceTest
Run 'AutomatedReportsServiceTest'
Debug 'AutomatedReportsServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
DATE_FILTER_KEYS
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
2/2
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
2
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Kiosk\AutomatedReports;
use Carbon\CarbonImmutable;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityActualDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\ActivityUpdatedDate;
use Jiminny\Component\ActivitySearch\FilterDefinition\DealInsights\ClosingPeriodFilter;
use Jiminny\Component\ActivitySearch\Service\ActivitySearch;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\User;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
class AskJiminnyReportActivityService
{
private const int DEFAULT_TOP_ACTIVITIES_COUNT = 100;
private const array DATE_FILTER_KEYS = [
ActivityActualDate::PARAM_START_DATE,
ActivityActualDate::PARAM_END_DATE,
ActivityUpdatedDate::PARAM_UPDATED_FROM,
ActivityUpdatedDate::PARAM_UPDATED_TO,
ClosingPeriodFilter::KEY_START_DATE,
ClosingPeriodFilter::KEY_END_DATE,
];
public function __construct(
private readonly ActivitySearch $activitySearch,
private readonly ElasticActivityRepository $elasticRepository,
private readonly LoggerInterface $logger,
) {
}
/**
* Fetch activity IDs for a saved search, passing its filters as-is to Criteria.
* Date filters stored on the saved search are excluded; if no other filters exist,
* no date constraint is applied — matching the behaviour of getContextForAskAnythingByFilter.
*
* @return string[] Activity IDs
*/
public function getActivityIdsForSavedSearch(
Search $savedSearch,
User $user,
?string $frequency = null,
): array {
$requestParams = $this->buildRequestParamsFromSearch($savedSearch, $user);
if ($frequency !== null) {
$dateRange = $this->calculateDateRangeForFrequency($frequency, $user);
if ($dateRange !== null) {
$requestParams[ActivityActualDate::PARAM_START_DATE] = $dateRange['start_date'];
$requestParams[ActivityActualDate::PARAM_END_DATE] = $dateRange['end_date'];
}
}
$criteria = Criteria::createFromRequest(
array_merge($requestParams, [
'limit' => self::DEFAULT_TOP_ACTIVITIES_COUNT,
'page' => 1,
'sequence_number' => 1,
]),
$user->getTimezone()
);
$filterSet = $this->activitySearch->getOnDemandPageFilterSet($criteria, $user);
$activityIds = $this->elasticRepository->onDemandSearchIdsOnly($user, $criteria, $filterSet);
$this->logger->info('[AskJiminnyReport] Fetched activity IDs for saved search', [
'saved_search_id' => $savedSearch->getId(),
'user_id' => $user->getId(),
'activity_count' => count($activityIds),
]);
return $activityIds;
}
private function buildRequestParamsFromSearch(Search $savedSearch, User $user): array
{
$params = [];
$arrayFilterKeys = $this->activitySearch->getArrayFilterKeys($user);
foreach ($savedSearch->getFilters() as $filter) {
$key = $filter->getFilterProperty();
$value = $filter->getFilterValue();
if (in_array($key, self::DATE_FILTER_KEYS, true)) {
continue;
}
if (isset($params[$key])) {
$params[$key][] = $value;
} elseif (in_array($key, $arrayFilterKeys, true)) {
$params[$key] = [$value];
} else {
$params[$key] = $value;
}
}
return $params;
}
/**
* @return array{start_date: string, end_date: string}|null
*/
private function calculateDateRangeForFrequency(string $frequency, User $user): ?array
{
$now = CarbonImmutable::now($user->getTimezone());
$range = match ($frequency) {
AutomatedReportsService::FREQUENCY_DAILY => [
$now->subDay()->startOfDay(),
$now->subDay()->endOfDay(),
],
AutomatedReportsService::FREQUENCY_WEEKLY => [
$now->subWeek()->startOfWeek(),
$now->subWeek()->endOfWeek(),
],
AutomatedReportsService::FREQUENCY_MONTHLY => [
$now->subMonthNoOverflow()->startOfMonth(),
$now->subMonthNoOverflow()->endOfMonth(),
],
AutomatedReportsService::FREQUENCY_QUARTERLY => [
$now->subQuarterNoOverflow()->startOfQuarter(),
$now->subQuarterNoOverflow()->endOfQuarter(),
],
default => null,
};
if ($range === null) {
return null;
}
return [
'start_date' => $range[0]->format('Y-m-d H:i:s'),
'end_date' => $range[1]->format('Y-m-d H:i:s'),
];
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
8
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Jobs\Crm;
use Exception;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Database\Connection;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Jiminny\Component\Queue\Constants;
use Jiminny\Exceptions\InvalidArgumentException;
use Jiminny\Jobs\Job;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Repositories\ActivityRepository;
use Jiminny\Services\Crm\CrmActivityService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Throwable;
class MatchActivityCrmData extends Job implements ShouldQueue, ShouldBeUnique
{
use InteractsWithQueue;
use SerializesModels;
public int $tries = 3;
private int $activityId;
private ?Configuration $fromConfiguration;
private bool $remoteSearch;
public function __construct(
int $activityId,
?Configuration $fromConfiguration = null,
bool $remoteSearch = false,
) {
$this->activityId = $activityId;
$this->fromConfiguration = $fromConfiguration;
$this->remoteSearch = $remoteSearch;
$this->onQueue(Constants::QUEUE_ANALYTICS_LOW);
}
public function uniqueId(): string
{
$configId = $this->fromConfiguration?->getId() ?? 0;
$remote = $this->remoteSearch ? 'remote' : 'local';
return "$this->activityId:$configId:$remote";
}
public function timeout(): int
{
return 300; // 5 minutes max execution time
}
public function uniqueFor(): int
{
return $this->timeout() + 60; // timeout + 1 minute buffer
}
public function backoff(): array
{
return [30, 90, 180];
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws Exception|Throwable
*/
public function handle(
ActivityRepository $activityRepository,
CrmActivityService $crmActivityService,
Connection $connection,
): void {
$activity = $activityRepository->findById($this->activityId);
if ($activity === null) {
throw new InvalidArgumentException('[MatchActivityCrmData] Cannot find activity.');
}
try {
$connection->transaction(function () use ($activity, $crmActivityService, $activityRepository) {
Log::info('[MatchActivityCrmData] Starting CRM data matching', [
'activity' => $this->activityId,
'remote_search' => $this->remoteSearch,
'set_configuration' => $this->fromConfiguration?->getId(),
'old_state' => [
'lead_id' => $activity->getLead()?->getId(),
'contact_id' => $activity->getContact()?->getId(),
'account_id' => $activity->getAccount()?->getId(),
'opportunity_id' => $activity->getOpportunity()?->getId(),
'stage_id' => $activity->getStage()?->getId(),
],
]);
$this->resetCrmMappings($activity, $activityRepository);
$this->switchCrmConfigurationIfNeeded($activity);
$activity->refresh();
$crmActivityService->updateCrmData(
activity: $activity,
remoteSearch: $this->remoteSearch,
);
$hasMatch = $activity->getLead() !== null
|| $activity->getContact() !== null
|| $activity->getAccount() !== null
|| $activity->getOpportunity() !== null;
if ($hasMatch) {
Log::info('[MatchActivityCrmData] Successfully matched CRM data', [
'activity' => $this->activityId,
'remote_search' => $this->remoteSearch,
'lead_id' => $activity->getLead()?->getId(),
'contact_id' => $activity->getContact()?->getId(),
'account_id' => $activity->getAccount()?->getId(),
'opportunity_id' => $activity->getOpportunity()?->getId(),
'stage_id' => $activity->getStage()?->getId(),
]);
} else {
Log::info('[MatchActivityCrmData] No CRM match found', [
'activity' => $this->activityId,
'remote_search' => $this->remoteSearch,
]);
}
});
} catch (Throwable $e) {
Log::error('[MatchActivityCrmData] Failed to match CRM data', [
'activity' => $this->activityId,
'remote_search' => $this->remoteSearch,
'exception' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
throw $e;
}
}
public function failed(Throwable $exception): void
{
Log::error('[MatchActivityCrmData] Job permanently failed after all retries', [
'activity' => $this->activityId,
'remote_search' => $this->remoteSearch,
'from_configuration' => $this->fromConfiguration?->getId(),
'exception' => $exception->getMessage(),
'attempts' => $this->attempts(),
]);
}
private function resetCrmMappings(
Activity $activity,
ActivityRepository $activityRepository
): void {
$activity->update([
'lead_id' => null,
'contact_id' => null,
'account_id' => null,
'opportunity_id' => null,
'stage_id' => null,
]);
$participantsOldState = $activityRepository->getActivityParticipants($activity)
->map(function ($participant) {
return [
'id' => $participant->id,
'user_id' => $participant->user_id,
'contact_id' => $participant->contact_id,
'lead_id' => $participant->lead_id,
];
});
if ($participantsOldState->isNotEmpty()) {
Log::info('[MatchActivityCrmData] Participants old state', [
'activity' => $this->activityId,
'participants' => $participantsOldState->toArray(),
]);
}
$activity->participants()->update([
'user_id' => null,
'contact_id' => null,
'lead_id' => null,
]);
}
private function switchCrmConfigurationIfNeeded(Activity $activity): void
{
if ($this->fromConfiguration === null) {
return;
}
if ($activity->getCrm()?->getId() === $this->fromConfiguration->getId()) {
return;
}
Log::info('[MatchActivityCrmData] Switching CRM configuration', [
'activity' => $this->activityId,
'old_configuration' => $activity->getCrm()?->getId(),
'new_configuration' => $this->fromConfiguration->getId(),
]);
$activity->update([
'crm_configuration_id' => $this->fromConfiguration->getId(),
'crm_provider_id' => null,
]);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf...
|
NULL
|
|
70232
|
1638
|
14
|
2026-04-22T09:58:47.809384+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-22/1776 /Users/lukas/.screenpipe/data/data/2026-04-22/1776851927809_m1.jpg...
|
Firefox
|
Formalize — Work
|
1
|
app-eu3.planhat.com/profile/677e7777f5db4de5da4a9b app-eu3.planhat.com/profile/677e7777f5db4de5da4a9b20?tab=overview...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST [URL_WITH_CREDENTIALS]
Sent Thanks for your time today!: Email logged by Tom on salesforce
Sent Thanks for your time today!: Email logged by Tom on salesforce
Mar 17, 2025
T
Hi ML Thanks for the chat today! We are still super excited about potentially working together We are here as a resource to hep and support anytime. Looking forward to continuing our collaboration
Formalize <> Jiminny- trial feedback 🚀
Formalize <> Jiminny- trial feedback 🚀
Mar 17, 2025
T
C
Summary The call focused on understanding the client's current evaluation of vendors and tools, as well as their decision-making criteria for selecting a solution that enhances productivity and effici
Sent Re: Formalize <> Jiminny- trial feedback 🚀: Email logged by Tom on salesforce
Sent Re: Formalize <> Jiminny- trial feedback 🚀: Email logged by Tom on salesforce
Mar 17, 2025
T
Hi Marie-Louise, No problem at all, I've moved this for you. Look forward to speaking later today. Best regards, Tom Tom Lavery *Founder & President* +44 7956 148 152 Book time with me | Conne
2
Formalize <> Jiminny- trial feedback 🚀
Formalize <> Jiminny- trial feedback 🚀
Mar 17, 2025
C
NS
T
Hi Marie-Louise, No problem at all, I've moved this for you. Look forward to speaking later today. Best regards, Tom Tom Lavery Founder & President +44 7956 148 152 Book time with me | Connect
February 2025
February 2025
Sent Re: Formalize <> Jiminny- trial feedback 🚀: Email logged by Tom on salesforce
Sent Re: Formalize <> Jiminny- trial feedback 🚀: Email logged by Tom on salesforce
Feb 27, 2025
T
Hi Marie-Louise, Thanks for letting us know. I moved it out two weeks :) Looking forward to meeting on the 17th March. Hope that works Tom Tom Lavery Founder & President Book a meeting | L
2
Formalize <> Jiminny- trial feedback 🚀
Formalize <> Jiminny- trial feedback 🚀
Feb 27, 2025
C
NS
T
Hi Marie-Louise, Thanks for letting us know. I moved it out two weeks :) Looking forward to meeting on the 17th March. Hope that works Tom Tom Lavery Founder & President Book a meeting | Let's...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20372] AI Reports > Empty page design and promotion - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20372] AI Reports > Empty page design and promotion - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny MCP Connector - Product - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny MCP Connector - Product - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Inbox (1,594) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox (1,594) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20500] Batch initial sync for Salesforce - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20500] Batch initial sync for Salesforce - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pipelines - /app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pipelines - /app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Formalize","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Formalize","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Search results: calendar | Jiminny Help Center","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search results: calendar | Jiminny Help Center","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Edit - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Edit - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-18909] [Part2] Automated reports with Ask Jiminny - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SevenShores\\Hubspot\\Exceptions\\BadRequest: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response: {\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Workers | Datadog","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Workers | Datadog","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.028819444,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.051736113,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.075,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.09826389,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.121527776,"top":0.0,"width":0.022222223,"height":0.035555556},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"L","depth":10,"bounds":{"left":0.19618055,"top":0.0,"width":0.027777778,"height":0.044444446},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"L","depth":11,"bounds":{"left":0.20694445,"top":0.0,"width":0.00625,"height":0.018888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"HEALTH","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Formalize","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"See in SalesForce","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"See in SalesForce","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Add a description","depth":12,"value":"Add a description","help_text":"","role_description":"text entry area","subrole":"AXApplicationGroup","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add a description","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Current Opp Forecast","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Stakeholders Involved","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Listener users","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"0","depth":13,"value":"0","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Handover CSM","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Retention Policy POC","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Owner","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny Customer Type","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Subscription Tier","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ARR of Prior Month","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":13,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Podcast POC Role","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Podcast POC Kiosk link","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Podcast Priority rating","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Renewal Forecast","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Client podcast requirements","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Podcast cadence","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"end Users number (Role)","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"17","depth":13,"value":"17","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Implementation Days","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":13,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Max Rec Seats Test","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":13,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Detraction Risk Rating","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"30 Days to Adoption Sign Off","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sales: 30 Days to Adoption","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Enablement Sessions","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":10,"bounds":{"left":0.240625,"top":0.0,"width":0.0055555557,"height":0.008888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Users billed","depth":11,"bounds":{"left":0.2517361,"top":0.0,"width":0.046875,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":13,"bounds":{"left":0.3482639,"top":0.0,"width":0.13333334,"height":0.020555556},"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Implementation progress","depth":11,"bounds":{"left":0.2517361,"top":0.0,"width":0.061458334,"height":0.033888888},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":0.0,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Up for renewal licences (Current ongoing contract)","depth":11,"bounds":{"left":0.2517361,"top":0.012222222,"width":0.09236111,"height":0.05277778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"0","depth":13,"bounds":{"left":0.3482639,"top":0.028888889,"width":0.13333334,"height":0.020555556},"value":"0","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":10,"bounds":{"left":0.240625,"top":0.08888889,"width":0.0055555557,"height":0.008888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Deal Insights Implementation","depth":11,"bounds":{"left":0.2517361,"top":0.08555555,"width":0.061458334,"height":0.033888888},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"bounds":{"left":0.3482639,"top":0.09277778,"width":0.13333334,"height":0.020555556},"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Executive Sponsor","depth":11,"bounds":{"left":0.2517361,"top":0.14555556,"width":0.072916664,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":15,"bounds":{"left":0.3482639,"top":0.145,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Implementation specialist","depth":11,"bounds":{"left":0.2517361,"top":0.18722223,"width":0.061458334,"height":0.033888888},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":15,"bounds":{"left":0.3482639,"top":0.19611111,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upsell owner/s","depth":11,"bounds":{"left":0.2517361,"top":0.24777777,"width":0.05798611,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":15,"bounds":{"left":0.3482639,"top":0.24666667,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ARR at End of Month","depth":11,"bounds":{"left":0.2517361,"top":0.295,"width":0.08090278,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":13,"bounds":{"left":0.3482639,"top":0.29277778,"width":0.13333334,"height":0.020555556},"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":10,"bounds":{"left":0.240625,"top":0.34,"width":0.0055555557,"height":0.008888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Next Strategic Milestone","depth":11,"bounds":{"left":0.2517361,"top":0.3361111,"width":0.05659722,"height":0.033888888},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"-","depth":12,"bounds":{"left":0.3482639,"top":0.34333333,"width":0.13333334,"height":0.020555556},"value":"-","help_text":"","role_description":"text entry area","subrole":"AXApplicationGroup","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":0.345,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Next steps","depth":11,"bounds":{"left":0.2517361,"top":0.39666668,"width":0.042013887,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"-","depth":12,"bounds":{"left":0.3482639,"top":0.39444444,"width":0.13333334,"height":0.020555556},"value":"-","help_text":"","role_description":"text entry area","subrole":"AXApplicationGroup","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":0.39555556,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":10,"bounds":{"left":0.240625,"top":0.44166666,"width":0.0055555557,"height":0.008888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ongoing Risk","depth":11,"bounds":{"left":0.2517361,"top":0.4438889,"width":0.052083332,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":0.44333333,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"HEALTH INDICATORS","depth":11,"bounds":{"left":0.2517361,"top":0.4911111,"width":0.083333336,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"bounds":{"left":0.3482639,"top":0.4888889,"width":0.13333334,"height":0.020555556},"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"NPS Score","depth":11,"bounds":{"left":0.2517361,"top":0.53833336,"width":0.041319445,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"not available","depth":13,"bounds":{"left":0.3482639,"top":0.5377778,"width":0.05277778,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":10,"bounds":{"left":0.240625,"top":0.5833333,"width":0.0055555557,"height":0.008888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Teams using Jiminny","depth":11,"bounds":{"left":0.2517361,"top":0.58555555,"width":0.08194444,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":0.585,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Features Set Up","depth":11,"bounds":{"left":0.2517361,"top":0.6333333,"width":0.063194446,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"*","depth":11,"bounds":{"left":0.31493056,"top":0.6333333,"width":0.005902778,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":0.63222224,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":10,"bounds":{"left":0.240625,"top":0.67833334,"width":0.0055555557,"height":0.008888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Features Adopted","depth":11,"bounds":{"left":0.2517361,"top":0.6805556,"width":0.07013889,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":0.67944443,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Adoption Risks","depth":11,"bounds":{"left":0.2517361,"top":0.7277778,"width":0.058680557,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"-","depth":12,"bounds":{"left":0.3482639,"top":0.72555554,"width":0.13333334,"height":0.020555556},"value":"-","help_text":"","role_description":"text entry area","subrole":"AXApplicationGroup","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":0.7266667,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":10,"bounds":{"left":0.240625,"top":0.7727778,"width":0.0055555557,"height":0.008888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ADDITIONAL PRODUCTS LINE","depth":11,"bounds":{"left":0.2517361,"top":0.7688889,"width":0.06493056,"height":0.033888888},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"-","depth":12,"bounds":{"left":0.3482639,"top":0.7761111,"width":0.13333334,"height":0.020555556},"value":"-","help_text":"","role_description":"text entry area","subrole":"AXApplicationGroup","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":0.7777778,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Product Name","depth":11,"bounds":{"left":0.2517361,"top":0.82944447,"width":0.05590278,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"-","depth":12,"bounds":{"left":0.3482639,"top":0.8272222,"width":0.13333334,"height":0.020555556},"value":"-","help_text":"","role_description":"text entry area","subrole":"AXApplicationGroup","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":0.8283333,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":10,"bounds":{"left":0.240625,"top":0.8744444,"width":0.0055555557,"height":0.008888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Teams Using Jiminny (Add product line)","depth":11,"bounds":{"left":0.2517361,"top":0.8711111,"width":0.08298611,"height":0.033888888},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":0.8794444,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Languages","depth":11,"bounds":{"left":0.2517361,"top":0.9311111,"width":0.042708334,"height":0.015},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":0.9305556,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Features set up (add product line)","depth":11,"bounds":{"left":0.2517361,"top":0.9727778,"width":0.081597224,"height":0.027222216},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":0.9811111,"width":0.004166667,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Features Adopted (Add product line)","depth":11,"bounds":{"left":0.2517361,"top":1.0,"width":0.09131944,"height":-0.027222276},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":1.0,"width":0.004166667,"height":-0.0355556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Adoption Risk (add product line)","depth":11,"bounds":{"left":0.2517361,"top":1.0,"width":0.075,"height":-0.08166671},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"-","depth":12,"bounds":{"left":0.3482639,"top":1.0,"width":0.13333334,"height":-0.08888888},"value":"-","help_text":"","role_description":"text entry area","subrole":"AXApplicationGroup","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"-","depth":14,"bounds":{"left":0.3482639,"top":1.0,"width":0.004166667,"height":-0.09000003},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"USER DETAIL","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Active Jiminny Instance","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NO","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"YES","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Trial held","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NO","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"YES","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Customer Status","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"prospect","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Phase","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Originally Contracted Licences","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":13,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Recording users","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"17","depth":13,"value":"17","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Live Insights users","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":13,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Voice users","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"0","depth":13,"value":"0","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CONTRACT INFORMATION","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Customer Since","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Renewal","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"prospect","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Renewal (in days)","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":13,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Auto-renew Active","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NO","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"YES","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Contracted user number (at agreement)","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":13,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Shelley Notes","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Petko Notes","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logging Workflow","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"-","depth":12,"value":"-","help_text":"","role_description":"text entry area","subrole":"AXApplicationGroup","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"-","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upsell next step","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"-","depth":12,"value":"-","help_text":"","role_description":"text entry area","subrole":"AXApplicationGroup","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"-","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upsell opportunity","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"-","depth":12,"value":"-","help_text":"","role_description":"text entry area","subrole":"AXApplicationGroup","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"-","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Integrations","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Decision Maker_","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Stakeholder/s","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Data Center","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"eu","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Months to retain data in Jiminny","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":13,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CRM","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"hubspot","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Email Provider","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"google","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Related Domains","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"formalize.com","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"whistleblowersoftware.com","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"formalize.com","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Account Status","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 week trial","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Followers","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Date Created","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Jan 08, 2025","depth":14,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jan 08, 2025","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"HQ Location","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":12,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Potential to return","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NO","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"YES","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sentiment score","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"-","depth":13,"value":"-","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"WORKFLOWS","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"WORKFLOWS","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Trial Workflow:","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Trial Workflow:","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(No one)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DELAYED","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Not Started","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"DOCUMENTS","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DOCUMENTS","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Upload your first document","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"create a new folder","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"OVERVIEW","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"END USERS","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(20)","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"USAGE","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"REVENUE","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DATA","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CHURN","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"INTERCOM CHATS","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"COMPANY USAGE","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"MORE","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"100","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"% OF UTILISED R…","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVITY GROWTH…","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PLAYBACK ADOPTI…","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"OD ADOPTION","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AJA ADOPTION","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DI ADOPTION","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TI ADOPTION","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"USAGE","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"USAGE","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Weeks ago","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"RECENTLY ACTIVE","depth":12,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"RECENTLY ACTIVE","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"MD Marie-Louise Dalsgaard a year ago 0","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"MD","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Marie-Louise Dalsgaard","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"a year ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"KØ Kasper Østergaard Hansen a year ago 0","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"KØ","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Kasper Østergaard Hansen","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"a year ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"SS Sofia Schulze Pröbsting a year ago 0","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SS","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sofia Schulze Pröbsting","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"a year ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"IJ Isabel Jerne a year ago 0","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"IJ","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Isabel Jerne","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"a year ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AJA ADOPTION LAST 30 DAYS","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"OD ADOPTION LAST 30 DAYS","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"DI ADOPTION LAST 30 DAYS","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TI ADOPTION LAST 30 DAYS","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ALLJIMINNYUSERSMETRIC","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PB ADOPTION LAST 30 DAYS","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"SHOW MORE","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SHOW MORE","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Planned","depth":12,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Planned","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Plan Activity","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"25 planned activities","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dec 17, 2024","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NO","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Placeholder for Jiminny","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jan 9, 2025","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NO","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Create internal Slack channel for the trial","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jan 9, 2025","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NO","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CSM and CE Assignment","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"SHOW ALL","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SHOW ALL","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Activities","depth":12,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Activities","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Search...","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0/110","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Log Activity","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Showing 45 out of 45 logged activities based on filter","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"May 2025","depth":12,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"May 2025","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"May 8, 2025","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi Marie-Louise, Please do not hesitate to reach out if there is anything we at Jiminny can do to support you during this trial period or once you have reached a conclusion. We would be very happy to","depth":15,"bounds":{"left":0.56458336,"top":0.0,"width":0.43541664,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"April 2025","depth":12,"bounds":{"left":0.54444444,"top":0.0,"width":0.45555556,"height":0.027777778},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"April 2025","depth":13,"bounds":{"left":0.54444444,"top":0.0,"width":0.05590278,"height":0.020555556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":16,"bounds":{"left":0.56458336,"top":0.06,"width":0.34236112,"height":0.022222223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":17,"bounds":{"left":0.56458336,"top":0.062222224,"width":0.34236112,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Apr 30, 2025","depth":16,"bounds":{"left":0.9458333,"top":0.06277778,"width":0.053819444,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi Marie-Louise, Thank you for the update. Please let us know if we can assist you during or after your trial period When can we sync to see what direction you are going in? Best regards, Tom Lav","depth":15,"bounds":{"left":0.56458336,"top":0.082777776,"width":0.43541664,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8","depth":15,"bounds":{"left":0.546875,"top":0.13,"width":0.004166667,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Thanks for your time today!","depth":16,"bounds":{"left":0.56458336,"top":0.12888889,"width":0.13055556,"height":0.022222223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Thanks for your time today!","depth":17,"bounds":{"left":0.56458336,"top":0.13111112,"width":0.13055556,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Apr 30, 2025","depth":16,"bounds":{"left":0.7340278,"top":0.13166666,"width":0.05347222,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"C","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"M","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi Marie-Louise, Thank you for the update. Please let us know if we can assist you during or after your trial period When can we sync to see what direction you are going in? Best regards, Tom Lavery","depth":15,"bounds":{"left":0.56458336,"top":0.15166667,"width":0.43541664,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Formalize sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":16,"bounds":{"left":0.56458336,"top":0.19777778,"width":0.39027777,"height":0.022222223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Formalize sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":17,"bounds":{"left":0.56458336,"top":0.2,"width":0.39027777,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Apr 30, 2025","depth":16,"bounds":{"left":0.99375,"top":0.20055556,"width":0.006250024,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"HI Tom Thanks for checking in. We are currently trialing another vendor and I will return if need be when we have some conclusions from that. Enjoy your day! On Tue, 29 Apr 2025 at 22:43, Tom Lave","depth":15,"bounds":{"left":0.56458336,"top":0.22055556,"width":0.43541664,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":16,"bounds":{"left":0.56458336,"top":0.26666668,"width":0.34236112,"height":0.022222223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":17,"bounds":{"left":0.56458336,"top":0.2688889,"width":0.34236112,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Apr 29, 2025","depth":16,"bounds":{"left":0.9458333,"top":0.26944444,"width":0.05347222,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi Marie-Louise, Following up on our conversations from March and April regarding Jiminny for Formalize, I wanted to see if you have an update on your decision process. Please let me know if you hav","depth":15,"bounds":{"left":0.56458336,"top":0.28944445,"width":0.43541664,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":16,"bounds":{"left":0.56458336,"top":0.33555555,"width":0.34236112,"height":0.022222223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":17,"bounds":{"left":0.56458336,"top":0.33777776,"width":0.34236112,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Apr 16, 2025","depth":16,"bounds":{"left":0.9458333,"top":0.33833334,"width":0.05277778,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi Marie-Louise, I hope you are well. Are you still considering Jiminny for Formalize? Be great to connect when you are free Thanks Tom Lavery *Founder & President* +44 7956 148 152 Book time","depth":15,"bounds":{"left":0.56458336,"top":0.35833332,"width":0.43541664,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":16,"bounds":{"left":0.56458336,"top":0.40444446,"width":0.34236112,"height":0.022222223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":17,"bounds":{"left":0.56458336,"top":0.40666667,"width":0.34236112,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Apr 7, 2025","depth":16,"bounds":{"left":0.9458333,"top":0.4072222,"width":0.047569446,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi Marie-Louise, I hope you are well, and you had a good weekend? I was wondering if you have made any decisions about which provider you will be moving forward with. Let me know when would be good","depth":15,"bounds":{"left":0.56458336,"top":0.42722222,"width":0.43541664,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"March 2025","depth":12,"bounds":{"left":0.54444444,"top":0.50555557,"width":0.45555556,"height":0.027777778},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"March 2025","depth":13,"bounds":{"left":0.54444444,"top":0.5094444,"width":0.063541666,"height":0.020555556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":16,"bounds":{"left":0.56458336,"top":0.5711111,"width":0.34236112,"height":0.022222223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":17,"bounds":{"left":0.56458336,"top":0.5733333,"width":0.34236112,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Mar 18, 2025","depth":16,"bounds":{"left":0.9458333,"top":0.5738889,"width":0.053819444,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi ML Happy to pick this up for you! So when we launch we train the team to use the translate button in Chrome it's very simple [image: image.png] You can download it here It's still just one","depth":15,"bounds":{"left":0.56458336,"top":0.5938889,"width":0.43541664,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Formalize sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":16,"bounds":{"left":0.56458336,"top":0.64,"width":0.39027777,"height":0.022222223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Formalize sent Re: Thanks for your time today!: Email logged by Tom on salesforce","depth":17,"bounds":{"left":0.56458336,"top":0.6422222,"width":0.39027777,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Mar 18, 2025","depth":16,"bounds":{"left":0.99375,"top":0.6427778,"width":0.006250024,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Likewise - really appreciate your support. One thing that has come up from my side: https://www.loom.com/share/664640adce384b09bfe6d0be29a6ac38?sid=a7400462-07d8-4b24-b62a-dd7cff3e873d Have a good d","depth":15,"bounds":{"left":0.56458336,"top":0.6627778,"width":0.43541664,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Formalize <> Jiminny- trial feedback 🚀: Discovery logged by Tom on salesforce","depth":16,"bounds":{"left":0.56458336,"top":0.7088889,"width":0.3767361,"height":0.022222223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Formalize <> Jiminny- trial feedback 🚀: Discovery logged by Tom on salesforce","depth":17,"bounds":{"left":0.56458336,"top":0.7111111,"width":0.3767361,"height":0.019444445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Mar 18, 2025","depth":16,"bounds":{"left":0.98020834,"top":0.71166664,"width":0.019791663,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jiminny Call Summary Call Duration: 12 minutes Review Activity: https://app.jiminny.com/playback/2f87646f-aea6-46b2-80d4-d1cb20ddaf30 Attendees: Marie-Louise Dalsgaard (marielouise.dalsgaard@formal","depth":15,"bounds":{"left":0.56458336,"top":0.7316667,"width":0.43541664,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Sent Thanks for your time today!: Email logged by Tom on salesforce","depth":16,"bounds":{"left":0.56458336,"top":0.7777778,"width":0.3246528,"height":0.022222223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sent Thanks for your time today!: Email logged by Tom on salesforce","depth":17,"bounds":{"left":0.56458336,"top":0.78,"width":0.3246528,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Mar 17, 2025","depth":16,"bounds":{"left":0.928125,"top":0.78055555,"width":0.052430555,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi ML Thanks for the chat today! We are still super excited about potentially working together We are here as a resource to hep and support anytime. Looking forward to continuing our collaboration","depth":15,"bounds":{"left":0.56458336,"top":0.8005555,"width":0.43541664,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Formalize <> Jiminny- trial feedback 🚀","depth":16,"bounds":{"left":0.56458336,"top":0.8466667,"width":0.1857639,"height":0.022222223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Formalize <> Jiminny- trial feedback 🚀","depth":17,"bounds":{"left":0.56458336,"top":0.8488889,"width":0.1857639,"height":0.019444445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Mar 17, 2025","depth":16,"bounds":{"left":0.7892361,"top":0.84944445,"width":0.05277778,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"C","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Summary The call focused on understanding the client's current evaluation of vendors and tools, as well as their decision-making criteria for selecting a solution that enhances productivity and effici","depth":15,"bounds":{"left":0.56458336,"top":0.86944443,"width":0.43541664,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Sent Re: Formalize <> Jiminny- trial feedback 🚀: Email logged by Tom on salesforce","depth":16,"bounds":{"left":0.56458336,"top":0.91555554,"width":0.39791667,"height":0.022222223},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sent Re: Formalize <> Jiminny- trial feedback 🚀: Email logged by Tom on salesforce","depth":17,"bounds":{"left":0.56458336,"top":0.9177778,"width":0.39791667,"height":0.019444445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Mar 17, 2025","depth":16,"bounds":{"left":1.0,"top":0.91833335,"width":-0.0013889074,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi Marie-Louise, No problem at all, I've moved this for you. Look forward to speaking later today. Best regards, Tom Tom Lavery *Founder & President* +44 7956 148 152 Book time with me | Conne","depth":15,"bounds":{"left":0.56458336,"top":0.93833333,"width":0.43541664,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":15,"bounds":{"left":0.5472222,"top":0.9855555,"width":0.0038194444,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Formalize <> Jiminny- trial feedback 🚀","depth":16,"bounds":{"left":0.56458336,"top":0.98444444,"width":0.1857639,"height":0.015555561},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Formalize <> Jiminny- trial feedback 🚀","depth":17,"bounds":{"left":0.56458336,"top":0.9866667,"width":0.1857639,"height":0.013333321},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Mar 17, 2025","depth":16,"bounds":{"left":0.7892361,"top":0.9872222,"width":0.05277778,"height":0.012777805},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"C","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NS","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi Marie-Louise, No problem at all, I've moved this for you. Look forward to speaking later today. Best regards, Tom Tom Lavery Founder & President +44 7956 148 152 Book time with me | Connect","depth":15,"bounds":{"left":0.56458336,"top":1.0,"width":0.43541664,"height":-0.0072221756},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"February 2025","depth":12,"bounds":{"left":0.54444444,"top":1.0,"width":0.45555556,"height":-0.08555555},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"February 2025","depth":13,"bounds":{"left":0.54444444,"top":1.0,"width":0.07847222,"height":-0.0894444},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Sent Re: Formalize <> Jiminny- trial feedback 🚀: Email logged by Tom on salesforce","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sent Re: Formalize <> Jiminny- trial feedback 🚀: Email logged by Tom on salesforce","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Feb 27, 2025","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi Marie-Louise, Thanks for letting us know. I moved it out two weeks :) Looking forward to meeting on the 17th March. Hope that works Tom Tom Lavery Founder & President Book a meeting | L","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Formalize <> Jiminny- trial feedback 🚀","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Formalize <> Jiminny- trial feedback 🚀","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Feb 27, 2025","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"C","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"NS","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"T","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi Marie-Louise, Thanks for letting us know. I moved it out two weeks :) Looking forward to meeting on the 17th March. Hope that works Tom Tom Lavery Founder & President Book a meeting | Let's","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
763843964971312725
|
8959460874414860296
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
SevenShores\Hubspot\Exceptions\BadRequest: Client error: `POST [URL_WITH_CREDENTIALS]
Sent Thanks for your time today!: Email logged by Tom on salesforce
Sent Thanks for your time today!: Email logged by Tom on salesforce
Mar 17, 2025
T
Hi ML Thanks for the chat today! We are still super excited about potentially working together We are here as a resource to hep and support anytime. Looking forward to continuing our collaboration
Formalize <> Jiminny- trial feedback 🚀
Formalize <> Jiminny- trial feedback 🚀
Mar 17, 2025
T
C
Summary The call focused on understanding the client's current evaluation of vendors and tools, as well as their decision-making criteria for selecting a solution that enhances productivity and effici
Sent Re: Formalize <> Jiminny- trial feedback 🚀: Email logged by Tom on salesforce
Sent Re: Formalize <> Jiminny- trial feedback 🚀: Email logged by Tom on salesforce
Mar 17, 2025
T
Hi Marie-Louise, No problem at all, I've moved this for you. Look forward to speaking later today. Best regards, Tom Tom Lavery *Founder & President* +44 7956 148 152 Book time with me | Conne
2
Formalize <> Jiminny- trial feedback 🚀
Formalize <> Jiminny- trial feedback 🚀
Mar 17, 2025
C
NS
T
Hi Marie-Louise, No problem at all, I've moved this for you. Look forward to speaking later today. Best regards, Tom Tom Lavery Founder & President +44 7956 148 152 Book time with me | Connect
February 2025
February 2025
Sent Re: Formalize <> Jiminny- trial feedback 🚀: Email logged by Tom on salesforce
Sent Re: Formalize <> Jiminny- trial feedback 🚀: Email logged by Tom on salesforce
Feb 27, 2025
T
Hi Marie-Louise, Thanks for letting us know. I moved it out two weeks :) Looking forward to meeting on the 17th March. Hope that works Tom Tom Lavery Founder & President Book a meeting | L
2
Formalize <> Jiminny- trial feedback 🚀
Formalize <> Jiminny- trial feedback 🚀
Feb 27, 2025
C
NS
T
Hi Marie-Louise, Thanks for letting us know. I moved it out two weeks :) Looking forward to meeting on the 17th March. Hope that works Tom Tom Lavery Founder & President Book a meeting | Let's...
|
70229
|
|
51728
|
1118
|
46
|
2026-04-20T06:19:46.084537+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-20/1776 /Users/lukas/.screenpipe/data/data/2026-04-20/1776665986084_m1.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (32)
Pull requests
(
32
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (28)
Security and quality
(
28
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
32 Open
32 Open
10,900 Closed
10,900 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
11 / 12 checks OK
#11989 opened
3 days ago
by
yalokin-jiminny
yalokin-jiminny
3 comments
3
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
12 / 12 checks OK
#11988 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
12 / 12 checks OK
#11987 opened
3 days ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
12 / 13 checks OK
#11986 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
3 comments
3
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
12 / 12 checks OK
#11984 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
1 comment
1
JY-9712 | change nudges schema
JY-9712 | change nudges schema
JY-9712 | change nudges schema
8 / 10 checks OK
#11983 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
21 / 21 checks OK
#11981 opened
4 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
5 comments
5
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
12 / 12 checks OK
#11980 opened
4 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
8 comments
8
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
12 / 12 checks OK
#11976 opened
4 days ago
by
yalokin-jiminny
yalokin-jiminny
•
Review required before merging
Review required
5 comments
5
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
8 / 10 checks OK
#11975 opened
4 days ago
by
github-actions
github-actions
bot
•
Review required before merging
Review required
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
8 / 10 checks OK
#11972 opened
5 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Draft
Draft
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
12 / 13 checks OK
#11970 opened
5 days ago
by
github-actions
github-actions
bot
•
3 review approvals
Approved
3 comments
3
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
7 / 11 checks OK
#11955 opened
last week
by
jamesgraham
jamesgraham
•
1 review approval
Approved
8 tasks
Fix fontawesome download issues
Fix fontawesome download issues
Fix fontawesome download issues
10 / 12 checks OK
#11895 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
5 comments
5
Ask Jiminny Reports
Ask Jiminny Reports
Ask Jiminny Reports
22 / 22 checks OK
#11894 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
6 comments
6
Jy 20405 zapier actions
Jy 20405 zapier actions
Jy 20405 zapier actions
11 / 12 checks OK...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Issues(g then i)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Pull requests","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Repositories","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (32)","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"32","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality (28)","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"28","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Filters","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:pr is:open","depth":11,"value":"is:pr is:open","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"32 Open","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"32 Open","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"10,900 Closed","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"10,900 Closed","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Author","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Label","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Projects","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Milestones","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reviews","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Sort","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11989 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":13,"help_text":"Open pull requests created by yalokin-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20698 handle failed field sync on playbook import activity types","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20698 handle failed field sync on playbook import activity types","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11988 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20695: Handle No raw transcript","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20695: Handle No raw transcript","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20695: Handle No raw transcript","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11987 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"mihailmihaylovjiminny","depth":13,"help_text":"Open pull requests created by mihailmihaylovjiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"mihailmihaylovjiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20692 change confirmation parameter","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20692 change confirmation parameter","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11986 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Add Makefile shortcuts for environment toggle commands","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Add Makefile shortcuts for environment toggle commands","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add Makefile shortcuts for environment toggle commands","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11984 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-9712 | change nudges schema","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-9712 | change nudges schema","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-9712 | change nudges schema","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11983 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-9712 | Nuges to expire after one year","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-9712 | Nuges to expire after one year","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-9712 | Nuges to expire after one year","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"21 / 21 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11981 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20541 remove crm contract method","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20541 remove crm contract method","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20541 remove crm contract method","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11980 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":13,"help_text":"Open pull requests created by Vasil-Jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"8 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"8","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20553 | Improve crm-sync delays","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20553 | Improve crm-sync delays","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20553 | Improve crm-sync delays","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11976 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":13,"help_text":"Open pull requests created by yalokin-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"fix(security): npm dependency updates – 2026-04-16","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"fix(security): npm dependency updates – 2026-04-16","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): npm dependency updates – 2026-04-16","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11975 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"github-actions","depth":13,"help_text":"Open pull requests created by github-actions[bot]","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"github-actions","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bot","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20541 cleanup stale tasks and events","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20541 cleanup stale tasks and events","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20541 cleanup stale tasks and events","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11972 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":13,"help_text":"Open pull requests created by Vasil-Jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"fix(security): composer dependency updates – 2026-04-15","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"fix(security): composer dependency updates – 2026-04-15","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11970 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"github-actions","depth":13,"help_text":"Open pull requests created by github-actions[bot]","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"github-actions","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bot","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 review approvals","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20663 Add Rockeed partner","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20663 Add Rockeed partner","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20663 Add Rockeed partner","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"7 / 11 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11955 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"last week","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"jamesgraham","depth":13,"help_text":"Open pull requests created by jamesgraham","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jamesgraham","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8 tasks","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Fix fontawesome download issues","depth":12,"bounds":{"left":0.15277778,"top":0.0,"width":0.009722223,"height":0.015555556},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Fix fontawesome download issues","depth":12,"bounds":{"left":0.19027779,"top":0.0,"width":0.17951389,"height":0.02111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fix fontawesome download issues","depth":13,"bounds":{"left":0.19027779,"top":0.0,"width":0.17951389,"height":0.02111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"10 / 12 checks OK","depth":13,"bounds":{"left":0.37256944,"top":0.0,"width":0.011111111,"height":0.023333333},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11895 opened","depth":13,"bounds":{"left":0.19027779,"top":0.0,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 weeks ago","depth":14,"bounds":{"left":0.253125,"top":0.0,"width":0.048958335,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.30208334,"top":0.0,"width":0.013888889,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolay-yankov","depth":13,"bounds":{"left":0.3159722,"top":0.0,"width":0.058680557,"height":0.016666668},"help_text":"Open pull requests created by nikolay-yankov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolay-yankov","depth":14,"bounds":{"left":0.3159722,"top":0.0,"width":0.058680557,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.37743056,"top":0.0,"width":0.00625,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.38368055,"top":0.0,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.38368055,"top":0.0,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"bounds":{"left":0.95416665,"top":0.0,"width":0.019444445,"height":0.018888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"bounds":{"left":0.96805555,"top":0.0,"width":0.0055555557,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Ask Jiminny Reports","depth":12,"bounds":{"left":0.15277778,"top":0.0,"width":0.009722223,"height":0.015555556},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Ask Jiminny Reports","depth":12,"bounds":{"left":0.19027779,"top":0.0,"width":0.10798611,"height":0.02111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny Reports","depth":13,"bounds":{"left":0.19027779,"top":0.0,"width":0.10798611,"height":0.02111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 22 checks OK","depth":13,"bounds":{"left":0.30104166,"top":0.0,"width":0.011111111,"height":0.023333333},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11894 opened","depth":13,"bounds":{"left":0.19027779,"top":0.016111111,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 weeks ago","depth":14,"bounds":{"left":0.253125,"top":0.016111111,"width":0.048958335,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.30208334,"top":0.016111111,"width":0.014236111,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolay-yankov","depth":13,"bounds":{"left":0.31631944,"top":0.016111111,"width":0.058333334,"height":0.016666668},"help_text":"Open pull requests created by nikolay-yankov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolay-yankov","depth":14,"bounds":{"left":0.31631944,"top":0.016111111,"width":0.058333334,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.37743056,"top":0.016111111,"width":0.00625,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.38368055,"top":0.016111111,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.38368055,"top":0.016111111,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"6 comments","depth":12,"bounds":{"left":0.95416665,"top":0.0,"width":0.019444445,"height":0.018888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"6","depth":13,"bounds":{"left":0.96770835,"top":0.0,"width":0.005902778,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20405 zapier actions","depth":12,"bounds":{"left":0.15277778,"top":0.05666667,"width":0.009722223,"height":0.015555556},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20405 zapier actions","depth":12,"bounds":{"left":0.19027779,"top":0.056111112,"width":0.12777779,"height":0.02111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20405 zapier actions","depth":13,"bounds":{"left":0.19027779,"top":0.056111112,"width":0.12777779,"height":0.02111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"bounds":{"left":0.3204861,"top":0.053333335,"width":0.011111111,"height":0.023333333},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
3675829678325842543
|
8954700339144789762
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (32)
Pull requests
(
32
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (28)
Security and quality
(
28
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
32 Open
32 Open
10,900 Closed
10,900 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
11 / 12 checks OK
#11989 opened
3 days ago
by
yalokin-jiminny
yalokin-jiminny
3 comments
3
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
12 / 12 checks OK
#11988 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
12 / 12 checks OK
#11987 opened
3 days ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
12 / 13 checks OK
#11986 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
3 comments
3
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
12 / 12 checks OK
#11984 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
1 comment
1
JY-9712 | change nudges schema
JY-9712 | change nudges schema
JY-9712 | change nudges schema
8 / 10 checks OK
#11983 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
21 / 21 checks OK
#11981 opened
4 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
5 comments
5
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
12 / 12 checks OK
#11980 opened
4 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
8 comments
8
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
12 / 12 checks OK
#11976 opened
4 days ago
by
yalokin-jiminny
yalokin-jiminny
•
Review required before merging
Review required
5 comments
5
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
8 / 10 checks OK
#11975 opened
4 days ago
by
github-actions
github-actions
bot
•
Review required before merging
Review required
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
8 / 10 checks OK
#11972 opened
5 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Draft
Draft
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
12 / 13 checks OK
#11970 opened
5 days ago
by
github-actions
github-actions
bot
•
3 review approvals
Approved
3 comments
3
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
7 / 11 checks OK
#11955 opened
last week
by
jamesgraham
jamesgraham
•
1 review approval
Approved
8 tasks
Fix fontawesome download issues
Fix fontawesome download issues
Fix fontawesome download issues
10 / 12 checks OK
#11895 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
5 comments
5
Ask Jiminny Reports
Ask Jiminny Reports
Ask Jiminny Reports
22 / 22 checks OK
#11894 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
6 comments
6
Jy 20405 zapier actions
Jy 20405 zapier actions
Jy 20405 zapier actions
11 / 12 checks OK...
|
51726
|
|
51737
|
1118
|
50
|
2026-04-20T06:19:57.559899+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-20/1776 /Users/lukas/.screenpipe/data/data/2026-04-20/1776665997559_m1.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (32)
Pull requests
(
32
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (28)
Security and quality
(
28
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
32 Open
32 Open
10,900 Closed
10,900 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
11 / 12 checks OK
#11989 opened
3 days ago
by
yalokin-jiminny
yalokin-jiminny
3 comments
3
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
12 / 12 checks OK
#11988 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
12 / 12 checks OK
#11987 opened
3 days ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
12 / 13 checks OK
#11986 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
3 comments
3
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
12 / 12 checks OK
#11984 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
1 comment
1
JY-9712 | change nudges schema
JY-9712 | change nudges schema
JY-9712 | change nudges schema
8 / 10 checks OK
#11983 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
21 / 21 checks OK
#11981 opened
4 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
5 comments
5
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
12 / 12 checks OK
#11980 opened
4 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
8 comments
8
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
12 / 12 checks OK
#11976 opened
4 days ago
by
yalokin-jiminny
yalokin-jiminny
•
Review required before merging
Review required
5 comments
5
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
8 / 10 checks OK
#11975 opened
4 days ago
by
github-actions
github-actions
bot
•
Review required before merging
Review required
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
8 / 10 checks OK
#11972 opened
5 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Draft
Draft
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
12 / 13 checks OK
#11970 opened
5 days ago
by
github-actions
github-actions
bot
•
3 review approvals
Approved
3 comments
3
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
7 / 11 checks OK
#11955 opened
last week
by
jamesgraham
jamesgraham
•
1 review approval
Approved
8 tasks
Fix fontawesome download issues
Fix fontawesome download issues
Fix fontawesome download issues
10 / 12 checks OK
#11895 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
5 comments
5
Ask Jiminny Reports
Ask Jiminny Reports
Ask Jiminny Reports
22 / 22 checks OK
#11894 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
6 comments
6
Jy 20405 zapier actions
Jy 20405 zapier actions
Jy 20405 zapier actions
11 / 12 checks OK...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Issues(g then i)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Pull requests","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Repositories","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (32)","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"32","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality (28)","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"28","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Filters","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:pr is:open","depth":11,"value":"is:pr is:open","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"32 Open","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"32 Open","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"10,900 Closed","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"10,900 Closed","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Author","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Label","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Projects","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Milestones","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reviews","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Sort","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11989 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":13,"help_text":"Open pull requests created by yalokin-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20698 handle failed field sync on playbook import activity types","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20698 handle failed field sync on playbook import activity types","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11988 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20695: Handle No raw transcript","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20695: Handle No raw transcript","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20695: Handle No raw transcript","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11987 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"mihailmihaylovjiminny","depth":13,"help_text":"Open pull requests created by mihailmihaylovjiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"mihailmihaylovjiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20692 change confirmation parameter","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20692 change confirmation parameter","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11986 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Add Makefile shortcuts for environment toggle commands","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Add Makefile shortcuts for environment toggle commands","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add Makefile shortcuts for environment toggle commands","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11984 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-9712 | change nudges schema","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-9712 | change nudges schema","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-9712 | change nudges schema","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11983 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-9712 | Nuges to expire after one year","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-9712 | Nuges to expire after one year","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-9712 | Nuges to expire after one year","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"21 / 21 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11981 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20541 remove crm contract method","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20541 remove crm contract method","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20541 remove crm contract method","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11980 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":13,"help_text":"Open pull requests created by Vasil-Jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"8 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"8","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20553 | Improve crm-sync delays","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20553 | Improve crm-sync delays","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20553 | Improve crm-sync delays","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11976 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":13,"help_text":"Open pull requests created by yalokin-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"fix(security): npm dependency updates – 2026-04-16","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"fix(security): npm dependency updates – 2026-04-16","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): npm dependency updates – 2026-04-16","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11975 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"github-actions","depth":13,"help_text":"Open pull requests created by github-actions[bot]","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"github-actions","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bot","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20541 cleanup stale tasks and events","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20541 cleanup stale tasks and events","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20541 cleanup stale tasks and events","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11972 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":13,"help_text":"Open pull requests created by Vasil-Jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"fix(security): composer dependency updates – 2026-04-15","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"fix(security): composer dependency updates – 2026-04-15","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11970 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"github-actions","depth":13,"help_text":"Open pull requests created by github-actions[bot]","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"github-actions","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bot","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 review approvals","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20663 Add Rockeed partner","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20663 Add Rockeed partner","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20663 Add Rockeed partner","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"7 / 11 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11955 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"last week","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"jamesgraham","depth":13,"help_text":"Open pull requests created by jamesgraham","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jamesgraham","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8 tasks","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Fix fontawesome download issues","depth":12,"bounds":{"left":0.15277778,"top":0.0,"width":0.009722223,"height":0.015555556},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Fix fontawesome download issues","depth":12,"bounds":{"left":0.19027779,"top":0.0,"width":0.17951389,"height":0.02111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fix fontawesome download issues","depth":13,"bounds":{"left":0.19027779,"top":0.0,"width":0.17951389,"height":0.02111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"10 / 12 checks OK","depth":13,"bounds":{"left":0.37256944,"top":0.0,"width":0.011111111,"height":0.023333333},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11895 opened","depth":13,"bounds":{"left":0.19027779,"top":0.0,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 weeks ago","depth":14,"bounds":{"left":0.253125,"top":0.0,"width":0.048958335,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.30208334,"top":0.0,"width":0.013888889,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolay-yankov","depth":13,"bounds":{"left":0.3159722,"top":0.0,"width":0.058680557,"height":0.016666668},"help_text":"Open pull requests created by nikolay-yankov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolay-yankov","depth":14,"bounds":{"left":0.3159722,"top":0.0,"width":0.058680557,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.37743056,"top":0.0,"width":0.00625,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.38368055,"top":0.0,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.38368055,"top":0.0,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"bounds":{"left":0.95416665,"top":0.0,"width":0.019444445,"height":0.018888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"bounds":{"left":0.96805555,"top":0.0,"width":0.0055555557,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Ask Jiminny Reports","depth":12,"bounds":{"left":0.15277778,"top":0.0,"width":0.009722223,"height":0.015555556},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Ask Jiminny Reports","depth":12,"bounds":{"left":0.19027779,"top":0.0,"width":0.10798611,"height":0.02111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny Reports","depth":13,"bounds":{"left":0.19027779,"top":0.0,"width":0.10798611,"height":0.02111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 22 checks OK","depth":13,"bounds":{"left":0.30104166,"top":0.0,"width":0.011111111,"height":0.023333333},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11894 opened","depth":13,"bounds":{"left":0.19027779,"top":0.016111111,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 weeks ago","depth":14,"bounds":{"left":0.253125,"top":0.016111111,"width":0.048958335,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.30208334,"top":0.016111111,"width":0.014236111,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolay-yankov","depth":13,"bounds":{"left":0.31631944,"top":0.016111111,"width":0.058333334,"height":0.016666668},"help_text":"Open pull requests created by nikolay-yankov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolay-yankov","depth":14,"bounds":{"left":0.31631944,"top":0.016111111,"width":0.058333334,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.37743056,"top":0.016111111,"width":0.00625,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.38368055,"top":0.016111111,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.38368055,"top":0.016111111,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"6 comments","depth":12,"bounds":{"left":0.95416665,"top":0.0,"width":0.019444445,"height":0.018888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"6","depth":13,"bounds":{"left":0.96770835,"top":0.0,"width":0.005902778,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20405 zapier actions","depth":12,"bounds":{"left":0.15277778,"top":0.05666667,"width":0.009722223,"height":0.015555556},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20405 zapier actions","depth":12,"bounds":{"left":0.19027779,"top":0.056111112,"width":0.12777779,"height":0.02111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20405 zapier actions","depth":13,"bounds":{"left":0.19027779,"top":0.056111112,"width":0.12777779,"height":0.02111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"bounds":{"left":0.3204861,"top":0.053333335,"width":0.011111111,"height":0.023333333},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
3675829678325842543
|
8954700339144789762
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (32)
Pull requests
(
32
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (28)
Security and quality
(
28
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
32 Open
32 Open
10,900 Closed
10,900 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
11 / 12 checks OK
#11989 opened
3 days ago
by
yalokin-jiminny
yalokin-jiminny
3 comments
3
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
12 / 12 checks OK
#11988 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
12 / 12 checks OK
#11987 opened
3 days ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
12 / 13 checks OK
#11986 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
3 comments
3
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
12 / 12 checks OK
#11984 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
1 comment
1
JY-9712 | change nudges schema
JY-9712 | change nudges schema
JY-9712 | change nudges schema
8 / 10 checks OK
#11983 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
21 / 21 checks OK
#11981 opened
4 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
5 comments
5
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
12 / 12 checks OK
#11980 opened
4 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
8 comments
8
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
12 / 12 checks OK
#11976 opened
4 days ago
by
yalokin-jiminny
yalokin-jiminny
•
Review required before merging
Review required
5 comments
5
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
8 / 10 checks OK
#11975 opened
4 days ago
by
github-actions
github-actions
bot
•
Review required before merging
Review required
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
8 / 10 checks OK
#11972 opened
5 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Draft
Draft
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
12 / 13 checks OK
#11970 opened
5 days ago
by
github-actions
github-actions
bot
•
3 review approvals
Approved
3 comments
3
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
7 / 11 checks OK
#11955 opened
last week
by
jamesgraham
jamesgraham
•
1 review approval
Approved
8 tasks
Fix fontawesome download issues
Fix fontawesome download issues
Fix fontawesome download issues
10 / 12 checks OK
#11895 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
5 comments
5
Ask Jiminny Reports
Ask Jiminny Reports
Ask Jiminny Reports
22 / 22 checks OK
#11894 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
6 comments
6
Jy 20405 zapier actions
Jy 20405 zapier actions
Jy 20405 zapier actions
11 / 12 checks OK...
|
51735
|
|
51729
|
1119
|
66
|
2026-04-20T06:19:46.084529+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-20/1776 /Users/lukas/.screenpipe/data/data/2026-04-20/1776665986084_m2.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (32)
Pull requests
(
32
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (28)
Security and quality
(
28
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
32 Open
32 Open
10,900 Closed
10,900 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
11 / 12 checks OK
#11989 opened
3 days ago
by
yalokin-jiminny
yalokin-jiminny
3 comments
3
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
12 / 12 checks OK
#11988 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
12 / 12 checks OK
#11987 opened
3 days ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
12 / 13 checks OK
#11986 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
3 comments
3
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
12 / 12 checks OK
#11984 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
1 comment
1
JY-9712 | change nudges schema
JY-9712 | change nudges schema
JY-9712 | change nudges schema
8 / 10 checks OK
#11983 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
21 / 21 checks OK
#11981 opened
4 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
5 comments
5
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
12 / 12 checks OK
#11980 opened
4 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
8 comments
8
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
12 / 12 checks OK
#11976 opened
4 days ago
by
yalokin-jiminny
yalokin-jiminny
•
Review required before merging
Review required
5 comments
5
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
8 / 10 checks OK
#11975 opened
4 days ago
by
github-actions
github-actions
bot
•
Review required before merging
Review required
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
8 / 10 checks OK
#11972 opened
5 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Draft
Draft
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
12 / 13 checks OK
#11970 opened
5 days ago
by
github-actions
github-actions
bot
•
3 review approvals
Approved
3 comments
3
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
7 / 11 checks OK
#11955 opened
last week
by
jamesgraham
jamesgraham
•
1 review approval
Approved
8 tasks
Fix fontawesome download issues
Fix fontawesome download issues
Fix fontawesome download issues
10 / 12 checks OK
#11895 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
5 comments
5
Ask Jiminny Reports
Ask Jiminny Reports
Ask Jiminny Reports
22 / 22 checks OK
#11894 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
6 comments
6
Jy 20405 zapier actions
Jy 20405 zapier actions
Jy 20405 zapier actions
11 / 12 checks OK
#11868 opened
3 weeks ago
by
jamesgraham
jamesgraham
•
Review required before merging
Review required
8 comments
8
Oxc
Oxc
Oxc
12 / 13 checks OK
#11824 opened
on Mar 19
by
des-d
des-d...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.0518755,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.06304868,"width":0.10106383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.08459697,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.09577015,"width":0.19963431,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.11731844,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.12849163,"width":0.15525267,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":4,"bounds":{"left":0.0,"top":0.15003991,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.16121309,"width":0.06981383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.18276137,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.19393456,"width":0.04537899,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.18994413,"width":0.007978723,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.21707901,"width":0.07413564,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.07962101,"top":0.047885075,"width":0.0003324468,"height":0.0007980846},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"bounds":{"left":0.07962101,"top":0.049481247,"width":0.0029920214,"height":0.21468475},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.08494016,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.099567816,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"bounds":{"left":0.112865694,"top":0.060654428,"width":0.018949468,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"bounds":{"left":0.11486037,"top":0.066640064,"width":0.014960106,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.13680187,"top":0.060654428,"width":0.017785905,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"bounds":{"left":0.13879654,"top":0.066640064,"width":0.008477394,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.060654428,"width":0.06565824,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.066640064,"width":0.011801862,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.06823623,"width":0.002493351,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.066640064,"width":0.021276595,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.060654428,"width":0.008643617,"height":0.025538707},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.060654428,"width":0.01662234,"height":0.025538707},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Repositories","depth":9,"bounds":{"left":0.9574468,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"bounds":{"left":0.9840425,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"bounds":{"left":0.079288565,"top":0.04708699,"width":0.0003324468,"height":0.0007980846},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.079288565,"top":0.04988029,"width":0.0787899,"height":0.023144454},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.08494016,"top":0.09537111,"width":0.025099734,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"bounds":{"left":0.095744684,"top":0.10175578,"width":0.011469414,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (32)","depth":12,"bounds":{"left":0.11269947,"top":0.09537111,"width":0.05501995,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"bounds":{"left":0.12333777,"top":0.10175578,"width":0.02925532,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.15525267,"top":0.10973663,"width":0.0029920214,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"32","depth":14,"bounds":{"left":0.15824468,"top":0.10973663,"width":0.0056515955,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.16389628,"top":0.10973663,"width":0.0016622341,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"bounds":{"left":0.17037898,"top":0.09537111,"width":0.029089095,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"bounds":{"left":0.18134974,"top":0.10175578,"width":0.01512633,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"bounds":{"left":0.20212767,"top":0.09537111,"width":0.03025266,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.21326463,"top":0.10175578,"width":0.015957447,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"bounds":{"left":0.23503989,"top":0.09537111,"width":0.022938829,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"bounds":{"left":0.24601063,"top":0.10175578,"width":0.009142287,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality (28)","depth":12,"bounds":{"left":0.2606383,"top":0.09537111,"width":0.070644945,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"bounds":{"left":0.27244017,"top":0.10175578,"width":0.04255319,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.31881648,"top":0.10973663,"width":0.0029920214,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"28","depth":14,"bounds":{"left":0.32180852,"top":0.10973663,"width":0.0056515955,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.3274601,"top":0.10973663,"width":0.0018284575,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"bounds":{"left":0.33394283,"top":0.09537111,"width":0.03125,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"bounds":{"left":0.34524602,"top":0.10175578,"width":0.016788565,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.3678524,"top":0.09537111,"width":0.032081116,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.37898937,"top":0.10175578,"width":0.017785905,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"bounds":{"left":0.09325133,"top":0.1396648,"width":0.0003324468,"height":0.016759777},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"bounds":{"left":0.09325133,"top":0.14126097,"width":0.039228722,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"bounds":{"left":0.09325133,"top":0.14126097,"width":0.2159242,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"bounds":{"left":0.30917552,"top":0.14126097,"width":0.04055851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"bounds":{"left":0.30917552,"top":0.14126097,"width":0.04055851,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"bounds":{"left":0.34973404,"top":0.14126097,"width":0.08261303,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"bounds":{"left":0.4323471,"top":0.14126097,"width":0.05219415,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"bounds":{"left":0.4323471,"top":0.14126097,"width":0.05219415,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.48454124,"top":0.14126097,"width":0.0013297872,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"bounds":{"left":0.98636967,"top":0.1348763,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"bounds":{"left":0.33776596,"top":0.18754987,"width":0.0003324468,"height":0.0007980846},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"bounds":{"left":0.33776596,"top":0.1915403,"width":0.04488032,"height":0.1452514},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"bounds":{"left":0.33776596,"top":0.18754987,"width":0.027426861,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Filters","depth":13,"bounds":{"left":0.34208778,"top":0.19353552,"width":0.013464096,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:pr is:open","depth":11,"bounds":{"left":0.3648604,"top":0.18754987,"width":0.23105054,"height":0.025538707},"value":"is:pr is:open","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"bounds":{"left":0.60123,"top":0.18754987,"width":0.043218084,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"bounds":{"left":0.6122008,"top":0.19353552,"width":0.016954787,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"bounds":{"left":0.6314827,"top":0.19513169,"width":0.004986702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"bounds":{"left":0.6441157,"top":0.18754987,"width":0.049534574,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"bounds":{"left":0.65508646,"top":0.19353552,"width":0.026263298,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.68367684,"top":0.19513169,"width":0.0019946808,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"bounds":{"left":0.69630986,"top":0.18754987,"width":0.045711435,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"bounds":{"left":0.7006317,"top":0.19353552,"width":0.03706782,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"bounds":{"left":0.34341756,"top":0.24181964,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"32 Open","depth":11,"bounds":{"left":0.35339096,"top":0.23942538,"width":0.026928192,"height":0.016759777},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"32 Open","depth":12,"bounds":{"left":0.3600399,"top":0.24102154,"width":0.020279255,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"10,900 Closed","depth":11,"bounds":{"left":0.3849734,"top":0.23942538,"width":0.03873005,"height":0.016759777},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"10,900 Closed","depth":12,"bounds":{"left":0.39162233,"top":0.24102154,"width":0.032081116,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"bounds":{"left":0.52925533,"top":0.23942538,"width":0.018284574,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Author","depth":12,"bounds":{"left":0.52925533,"top":0.24102154,"width":0.015625,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"bounds":{"left":0.5581782,"top":0.23942538,"width":0.015625,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Label","depth":12,"bounds":{"left":0.5581782,"top":0.24102154,"width":0.012965426,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","depth":12,"bounds":{"left":0.5844415,"top":0.23942538,"width":0.02144282,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Projects","depth":13,"bounds":{"left":0.5844415,"top":0.24102154,"width":0.018783245,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","depth":12,"bounds":{"left":0.6178524,"top":0.23942538,"width":0.027260639,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Milestones","depth":13,"bounds":{"left":0.6178524,"top":0.24102154,"width":0.024601065,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","depth":12,"bounds":{"left":0.6570811,"top":0.23942538,"width":0.02144282,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reviews","depth":13,"bounds":{"left":0.6570811,"top":0.24102154,"width":0.018783245,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"bounds":{"left":0.68916225,"top":0.23942538,"width":0.0234375,"height":0.016759777},"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"bounds":{"left":0.68916225,"top":0.24102154,"width":0.020777926,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"bounds":{"left":0.72323805,"top":0.23942538,"width":0.013131649,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Sort","depth":12,"bounds":{"left":0.72323805,"top":0.24102154,"width":0.009142287,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"bounds":{"left":0.3380984,"top":0.2697526,"width":0.0003324468,"height":0.0007980846},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"bounds":{"left":0.3380984,"top":0.2725459,"width":0.03174867,"height":0.08060654},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":12,"bounds":{"left":0.34341756,"top":0.2793296,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":12,"bounds":{"left":0.36136967,"top":0.2793296,"width":0.11619016,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":13,"bounds":{"left":0.36136967,"top":0.2793296,"width":0.11619016,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"bounds":{"left":0.4788896,"top":0.27693537,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11989 opened","depth":13,"bounds":{"left":0.36136967,"top":0.3008779,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"bounds":{"left":0.39145613,"top":0.3008779,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41206783,"top":0.3008779,"width":0.0066489363,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":13,"bounds":{"left":0.41871676,"top":0.3008779,"width":0.02825798,"height":0.011971269},"help_text":"Open pull requests created by yalokin-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":14,"bounds":{"left":0.41871676,"top":0.3008779,"width":0.02825798,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"bounds":{"left":0.72706115,"top":0.27853152,"width":0.00930851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"bounds":{"left":0.7337101,"top":0.2801277,"width":0.0026595744,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20698 handle failed field sync on playbook import activity types","depth":12,"bounds":{"left":0.34341756,"top":0.33000797,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20698 handle failed field sync on playbook import activity types","depth":12,"bounds":{"left":0.36136967,"top":0.32960895,"width":0.17087767,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types","depth":13,"bounds":{"left":0.36136967,"top":0.32960895,"width":0.17087767,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"bounds":{"left":0.53357714,"top":0.32761374,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11988 opened","depth":13,"bounds":{"left":0.36136967,"top":0.35115722,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"bounds":{"left":0.39145613,"top":0.35115722,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41206783,"top":0.35115722,"width":0.0066489363,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.41871676,"top":0.35115722,"width":0.015458777,"height":0.011971269},"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.41871676,"top":0.35115722,"width":0.015458777,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.43550533,"top":0.35115722,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.43849733,"top":0.35115722,"width":0.03025266,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.43849733,"top":0.35115722,"width":0.03025266,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.72772604,"top":0.3292099,"width":0.008643617,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.734375,"top":0.33080608,"width":0.0019946808,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20695: Handle No raw transcript","depth":12,"bounds":{"left":0.34341756,"top":0.38028732,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20695: Handle No raw transcript","depth":12,"bounds":{"left":0.36136967,"top":0.38028732,"width":0.09158909,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20695: Handle No raw transcript","depth":13,"bounds":{"left":0.36136967,"top":0.38028732,"width":0.09158909,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"bounds":{"left":0.45428857,"top":0.37789306,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11987 opened","depth":13,"bounds":{"left":0.36136967,"top":0.4018356,"width":0.029920213,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"bounds":{"left":0.3912899,"top":0.4018356,"width":0.02044548,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.4117354,"top":0.4018356,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"mihailmihaylovjiminny","depth":13,"bounds":{"left":0.41855052,"top":0.4018356,"width":0.040724736,"height":0.011971269},"help_text":"Open pull requests created by mihailmihaylovjiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"mihailmihaylovjiminny","depth":14,"bounds":{"left":0.41855052,"top":0.4018356,"width":0.040724736,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.46060506,"top":0.4018356,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.4635971,"top":0.4018356,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.4635971,"top":0.4018356,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.72772604,"top":0.3794892,"width":0.008643617,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.734375,"top":0.3810854,"width":0.0019946808,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20692 change confirmation parameter","depth":12,"bounds":{"left":0.34341756,"top":0.4309657,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20692 change confirmation parameter","depth":12,"bounds":{"left":0.36136967,"top":0.4309657,"width":0.10638298,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter","depth":13,"bounds":{"left":0.36136967,"top":0.4309657,"width":0.10638298,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"bounds":{"left":0.46908244,"top":0.42857143,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11986 opened","depth":13,"bounds":{"left":0.36136967,"top":0.45251396,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"bounds":{"left":0.39145613,"top":0.45251396,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41206783,"top":0.45251396,"width":0.0066489363,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.41871676,"top":0.45251396,"width":0.015458777,"height":0.011971269},"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.41871676,"top":0.45251396,"width":0.015458777,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.43550533,"top":0.45251396,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.43849733,"top":0.45251396,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.43849733,"top":0.45251396,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"bounds":{"left":0.72706115,"top":0.4301676,"width":0.00930851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"bounds":{"left":0.7337101,"top":0.43176377,"width":0.0026595744,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Add Makefile shortcuts for environment toggle commands","depth":12,"bounds":{"left":0.34341756,"top":0.48164406,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Add Makefile shortcuts for environment toggle commands","depth":12,"bounds":{"left":0.36136967,"top":0.481245,"width":0.14660904,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add Makefile shortcuts for environment toggle commands","depth":13,"bounds":{"left":0.36136967,"top":0.481245,"width":0.14660904,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"bounds":{"left":0.5093085,"top":0.4792498,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11984 opened","depth":13,"bounds":{"left":0.36136967,"top":0.5027933,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"bounds":{"left":0.39145613,"top":0.5027933,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41206783,"top":0.5027933,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"bounds":{"left":0.41888297,"top":0.5027933,"width":0.030585106,"height":0.011971269},"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"bounds":{"left":0.41888297,"top":0.5027933,"width":0.030585106,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.4507979,"top":0.5027933,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.4537899,"top":0.5027933,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.4537899,"top":0.5027933,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.72772604,"top":0.48084596,"width":0.008643617,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.734375,"top":0.48244214,"width":0.0019946808,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-9712 | change nudges schema","depth":12,"bounds":{"left":0.34341756,"top":0.5319234,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-9712 | change nudges schema","depth":12,"bounds":{"left":0.36136967,"top":0.5319234,"width":0.084773935,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-9712 | change nudges schema","depth":13,"bounds":{"left":0.36136967,"top":0.5319234,"width":0.084773935,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"bounds":{"left":0.4474734,"top":0.52952915,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11983 opened","depth":13,"bounds":{"left":0.36136967,"top":0.5534717,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"bounds":{"left":0.39145613,"top":0.5534717,"width":0.02044548,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.4119016,"top":0.5534717,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"bounds":{"left":0.41871676,"top":0.5534717,"width":0.030751329,"height":0.011971269},"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"bounds":{"left":0.41871676,"top":0.5534717,"width":0.030751329,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.4507979,"top":0.5534717,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.4537899,"top":0.5534717,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.4537899,"top":0.5534717,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-9712 | Nuges to expire after one year","depth":12,"bounds":{"left":0.34341756,"top":0.5826017,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-9712 | Nuges to expire after one year","depth":12,"bounds":{"left":0.36136967,"top":0.58220273,"width":0.101230055,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-9712 | Nuges to expire after one year","depth":13,"bounds":{"left":0.36136967,"top":0.58220273,"width":0.101230055,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"21 / 21 checks OK","depth":13,"bounds":{"left":0.46392953,"top":0.5802075,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11981 opened","depth":13,"bounds":{"left":0.36136967,"top":0.603751,"width":0.029421542,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"bounds":{"left":0.39079124,"top":0.603751,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.4114029,"top":0.603751,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"bounds":{"left":0.41821808,"top":0.603751,"width":0.030585106,"height":0.011971269},"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"bounds":{"left":0.41821808,"top":0.603751,"width":0.030585106,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.45013297,"top":0.603751,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.453125,"top":0.603751,"width":0.03025266,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.453125,"top":0.603751,"width":0.03025266,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"bounds":{"left":0.72706115,"top":0.5818037,"width":0.00930851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"bounds":{"left":0.7337101,"top":0.58339983,"width":0.0026595744,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20541 remove crm contract method","depth":12,"bounds":{"left":0.34341756,"top":0.6328811,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20541 remove crm contract method","depth":12,"bounds":{"left":0.36136967,"top":0.6328811,"width":0.09823803,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20541 remove crm contract method","depth":13,"bounds":{"left":0.36136967,"top":0.6328811,"width":0.09823803,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"bounds":{"left":0.46077126,"top":0.63048685,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11980 opened","depth":13,"bounds":{"left":0.36136967,"top":0.6544294,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"bounds":{"left":0.39145613,"top":0.6544294,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41206783,"top":0.6544294,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":13,"bounds":{"left":0.41888297,"top":0.6544294,"width":0.024933511,"height":0.011971269},"help_text":"Open pull requests created by Vasil-Jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":14,"bounds":{"left":0.41888297,"top":0.6544294,"width":0.024933511,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.44514626,"top":0.6544294,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.4481383,"top":0.6544294,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.4481383,"top":0.6544294,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"8 comments","depth":12,"bounds":{"left":0.726895,"top":0.632083,"width":0.009474734,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"8","depth":13,"bounds":{"left":0.7335439,"top":0.63367915,"width":0.0028257978,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20553 | Improve crm-sync delays","depth":12,"bounds":{"left":0.34341756,"top":0.6835595,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20553 | Improve crm-sync delays","depth":12,"bounds":{"left":0.36136967,"top":0.6835595,"width":0.09325133,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20553 | Improve crm-sync delays","depth":13,"bounds":{"left":0.36136967,"top":0.6835595,"width":0.09325133,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"bounds":{"left":0.4559508,"top":0.6811652,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11976 opened","depth":13,"bounds":{"left":0.36136967,"top":0.70510775,"width":0.029753989,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"bounds":{"left":0.39112368,"top":0.70510775,"width":0.02044548,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41156915,"top":0.70510775,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":13,"bounds":{"left":0.4183843,"top":0.70510775,"width":0.02825798,"height":0.011971269},"help_text":"Open pull requests created by yalokin-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":14,"bounds":{"left":0.4183843,"top":0.70510775,"width":0.02825798,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.4479721,"top":0.70510775,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.4509641,"top":0.70510775,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.4509641,"top":0.70510775,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"bounds":{"left":0.72706115,"top":0.6827614,"width":0.00930851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"bounds":{"left":0.7337101,"top":0.6843575,"width":0.0026595744,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"fix(security): npm dependency updates – 2026-04-16","depth":12,"bounds":{"left":0.34341756,"top":0.73423785,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"fix(security): npm dependency updates – 2026-04-16","depth":12,"bounds":{"left":0.36136967,"top":0.7338388,"width":0.13663563,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): npm dependency updates – 2026-04-16","depth":13,"bounds":{"left":0.36136967,"top":0.7338388,"width":0.13663563,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"bounds":{"left":0.4993351,"top":0.7318436,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11975 opened","depth":13,"bounds":{"left":0.36136967,"top":0.7561852,"width":0.029587766,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"bounds":{"left":0.39095744,"top":0.7561852,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41156915,"top":0.7561852,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"github-actions","depth":13,"bounds":{"left":0.4183843,"top":0.7561852,"width":0.027593086,"height":0.011971269},"help_text":"Open pull requests created by github-actions[bot]","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"github-actions","depth":14,"bounds":{"left":0.4183843,"top":0.7561852,"width":0.027593086,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bot","depth":14,"bounds":{"left":0.44946808,"top":0.7561852,"width":0.0063164895,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.45944148,"top":0.75538707,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.46243352,"top":0.75538707,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.46243352,"top":0.75538707,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20541 cleanup stale tasks and events","depth":12,"bounds":{"left":0.34341756,"top":0.7861133,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20541 cleanup stale tasks and events","depth":12,"bounds":{"left":0.36136967,"top":0.7861133,"width":0.1022274,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20541 cleanup stale tasks and events","depth":13,"bounds":{"left":0.36136967,"top":0.7861133,"width":0.1022274,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"bounds":{"left":0.46476063,"top":0.78371906,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11972 opened","depth":13,"bounds":{"left":0.36136967,"top":0.8076616,"width":0.029587766,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 days ago","depth":14,"bounds":{"left":0.39095744,"top":0.8076616,"width":0.02044548,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.4114029,"top":0.8076616,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":13,"bounds":{"left":0.41821808,"top":0.8076616,"width":0.024933511,"height":0.011971269},"help_text":"Open pull requests created by Vasil-Jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":14,"bounds":{"left":0.41821808,"top":0.8076616,"width":0.024933511,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.44448137,"top":0.8076616,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.4474734,"top":0.8076616,"width":0.009640957,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.4474734,"top":0.8076616,"width":0.009640957,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"fix(security): composer dependency updates – 2026-04-15","depth":12,"bounds":{"left":0.34341756,"top":0.8367917,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"fix(security): composer dependency updates – 2026-04-15","depth":12,"bounds":{"left":0.36136967,"top":0.8367917,"width":0.1505984,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15","depth":13,"bounds":{"left":0.36136967,"top":0.8367917,"width":0.1505984,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"bounds":{"left":0.51329786,"top":0.83439744,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11970 opened","depth":13,"bounds":{"left":0.36136967,"top":0.8591381,"width":0.029753989,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 days ago","depth":14,"bounds":{"left":0.39112368,"top":0.8591381,"width":0.02044548,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41156915,"top":0.8591381,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"github-actions","depth":13,"bounds":{"left":0.4183843,"top":0.8591381,"width":0.027426861,"height":0.011971269},"help_text":"Open pull requests created by github-actions[bot]","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"github-actions","depth":14,"bounds":{"left":0.4183843,"top":0.8591381,"width":0.027426861,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bot","depth":14,"bounds":{"left":0.44930187,"top":0.8591381,"width":0.006482713,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.45944148,"top":0.85833997,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 review approvals","depth":13,"bounds":{"left":0.46243352,"top":0.85833997,"width":0.018118352,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"bounds":{"left":0.46243352,"top":0.85833997,"width":0.018118352,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"bounds":{"left":0.72706115,"top":0.8359936,"width":0.00930851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"bounds":{"left":0.7337101,"top":0.8375898,"width":0.0026595744,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20663 Add Rockeed partner","depth":12,"bounds":{"left":0.34341756,"top":0.8890662,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20663 Add Rockeed partner","depth":12,"bounds":{"left":0.36136967,"top":0.8886672,"width":0.08028591,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20663 Add Rockeed partner","depth":13,"bounds":{"left":0.36136967,"top":0.8886672,"width":0.08028591,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"7 / 11 checks OK","depth":13,"bounds":{"left":0.4429854,"top":0.88667196,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11955 opened","depth":13,"bounds":{"left":0.36136967,"top":0.9102155,"width":0.029920213,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"last week","depth":14,"bounds":{"left":0.3912899,"top":0.9102155,"width":0.01761968,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.4089096,"top":0.9102155,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"jamesgraham","depth":13,"bounds":{"left":0.41572472,"top":0.9102155,"width":0.025099734,"height":0.011971269},"help_text":"Open pull requests created by jamesgraham","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jamesgraham","depth":14,"bounds":{"left":0.41572472,"top":0.9102155,"width":0.025099734,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.44215426,"top":0.9102155,"width":0.0031582448,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"bounds":{"left":0.4453125,"top":0.9102155,"width":0.017952127,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"bounds":{"left":0.4453125,"top":0.9102155,"width":0.017952127,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8 tasks","depth":14,"bounds":{"left":0.47257313,"top":0.9102155,"width":0.013630319,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Fix fontawesome download issues","depth":12,"bounds":{"left":0.34341756,"top":0.9393456,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Fix fontawesome download issues","depth":12,"bounds":{"left":0.36136967,"top":0.9393456,"width":0.0859375,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fix fontawesome download issues","depth":13,"bounds":{"left":0.36136967,"top":0.9393456,"width":0.0859375,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"10 / 12 checks OK","depth":13,"bounds":{"left":0.44863698,"top":0.93695134,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11895 opened","depth":13,"bounds":{"left":0.36136967,"top":0.96089387,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 weeks ago","depth":14,"bounds":{"left":0.39145613,"top":0.96089387,"width":0.0234375,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41489363,"top":0.96089387,"width":0.0066489363,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolay-yankov","depth":13,"bounds":{"left":0.42154256,"top":0.96089387,"width":0.028091755,"height":0.011971269},"help_text":"Open pull requests created by nikolay-yankov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolay-yankov","depth":14,"bounds":{"left":0.42154256,"top":0.96089387,"width":0.028091755,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.4509641,"top":0.96089387,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.45395613,"top":0.96089387,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.45395613,"top":0.96089387,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"bounds":{"left":0.72706115,"top":0.9385475,"width":0.00930851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"bounds":{"left":0.7337101,"top":0.94014364,"width":0.0026595744,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Ask Jiminny Reports","depth":12,"bounds":{"left":0.34341756,"top":0.990024,"width":0.004654255,"height":0.009976029},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Ask Jiminny Reports","depth":12,"bounds":{"left":0.36136967,"top":0.990024,"width":0.051695477,"height":0.009976029},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny Reports","depth":13,"bounds":{"left":0.36136967,"top":0.990024,"width":0.051695477,"height":0.009976029},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 22 checks OK","depth":13,"bounds":{"left":0.41439494,"top":0.9876297,"width":0.005319149,"height":0.012370288},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11894 opened","depth":13,"bounds":{"left":0.36136967,"top":1.0,"width":0.030086435,"height":-0.011572242},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 weeks ago","depth":14,"bounds":{"left":0.39145613,"top":1.0,"width":0.0234375,"height":-0.011572242},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41489363,"top":1.0,"width":0.0068151597,"height":-0.011572242},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolay-yankov","depth":13,"bounds":{"left":0.42170876,"top":1.0,"width":0.027925532,"height":-0.011572242},"help_text":"Open pull requests created by nikolay-yankov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolay-yankov","depth":14,"bounds":{"left":0.42170876,"top":1.0,"width":0.027925532,"height":-0.011572242},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.4509641,"top":1.0,"width":0.0029920214,"height":-0.011572242},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.45395613,"top":1.0,"width":0.030086435,"height":-0.011572242},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.45395613,"top":1.0,"width":0.030086435,"height":-0.011572242},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"6 comments","depth":12,"bounds":{"left":0.72706115,"top":0.98922586,"width":0.00930851,"height":0.010774136},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"6","depth":13,"bounds":{"left":0.7335439,"top":0.990822,"width":0.0028257978,"height":0.009177983},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20405 zapier actions","depth":12,"bounds":{"left":0.34341756,"top":1.0,"width":0.004654255,"height":-0.040702343},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20405 zapier actions","depth":12,"bounds":{"left":0.36136967,"top":1.0,"width":0.061170213,"height":-0.04030323},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20405 zapier actions","depth":13,"bounds":{"left":0.36136967,"top":1.0,"width":0.061170213,"height":-0.04030323},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"bounds":{"left":0.42370346,"top":1.0,"width":0.005319149,"height":-0.038308024},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11868 opened","depth":13,"bounds":{"left":0.36136967,"top":1.0,"width":0.030086435,"height":-0.0618515},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 weeks ago","depth":14,"bounds":{"left":0.39145613,"top":1.0,"width":0.023603724,"height":-0.0618515},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41505983,"top":1.0,"width":0.0066489363,"height":-0.0618515},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"jamesgraham","depth":13,"bounds":{"left":0.42170876,"top":1.0,"width":0.025265958,"height":-0.0618515},"help_text":"Open pull requests created by jamesgraham","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jamesgraham","depth":14,"bounds":{"left":0.42170876,"top":1.0,"width":0.025265958,"height":-0.0618515},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.44830453,"top":1.0,"width":0.0029920214,"height":-0.0618515},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.45129654,"top":1.0,"width":0.030086435,"height":-0.0618515},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.45129654,"top":1.0,"width":0.030086435,"height":-0.0618515},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"8 comments","depth":12,"bounds":{"left":0.726895,"top":1.0,"width":0.009474734,"height":-0.039904237},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"8","depth":13,"bounds":{"left":0.7335439,"top":1.0,"width":0.0028257978,"height":-0.04150045},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Oxc","depth":12,"bounds":{"left":0.34341756,"top":1.0,"width":0.004654255,"height":-0.0909816},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Oxc","depth":12,"bounds":{"left":0.36136967,"top":1.0,"width":0.009640957,"height":-0.0909816},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Oxc","depth":13,"bounds":{"left":0.36136967,"top":1.0,"width":0.009640957,"height":-0.0909816},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"bounds":{"left":0.3723404,"top":1.0,"width":0.005319149,"height":-0.0885874},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11824 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on Mar 19","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"des-d","depth":13,"help_text":"Open pull requests created by des-d","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"des-d","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-2014955340950047857
|
8954691543051766530
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (32)
Pull requests
(
32
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (28)
Security and quality
(
28
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
32 Open
32 Open
10,900 Closed
10,900 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
11 / 12 checks OK
#11989 opened
3 days ago
by
yalokin-jiminny
yalokin-jiminny
3 comments
3
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
12 / 12 checks OK
#11988 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
12 / 12 checks OK
#11987 opened
3 days ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
12 / 13 checks OK
#11986 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
3 comments
3
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
12 / 12 checks OK
#11984 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
1 comment
1
JY-9712 | change nudges schema
JY-9712 | change nudges schema
JY-9712 | change nudges schema
8 / 10 checks OK
#11983 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
21 / 21 checks OK
#11981 opened
4 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
5 comments
5
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
12 / 12 checks OK
#11980 opened
4 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
8 comments
8
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
12 / 12 checks OK
#11976 opened
4 days ago
by
yalokin-jiminny
yalokin-jiminny
•
Review required before merging
Review required
5 comments
5
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
8 / 10 checks OK
#11975 opened
4 days ago
by
github-actions
github-actions
bot
•
Review required before merging
Review required
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
8 / 10 checks OK
#11972 opened
5 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Draft
Draft
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
12 / 13 checks OK
#11970 opened
5 days ago
by
github-actions
github-actions
bot
•
3 review approvals
Approved
3 comments
3
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
7 / 11 checks OK
#11955 opened
last week
by
jamesgraham
jamesgraham
•
1 review approval
Approved
8 tasks
Fix fontawesome download issues
Fix fontawesome download issues
Fix fontawesome download issues
10 / 12 checks OK
#11895 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
5 comments
5
Ask Jiminny Reports
Ask Jiminny Reports
Ask Jiminny Reports
22 / 22 checks OK
#11894 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
6 comments
6
Jy 20405 zapier actions
Jy 20405 zapier actions
Jy 20405 zapier actions
11 / 12 checks OK
#11868 opened
3 weeks ago
by
jamesgraham
jamesgraham
•
Review required before merging
Review required
8 comments
8
Oxc
Oxc
Oxc
12 / 13 checks OK
#11824 opened
on Mar 19
by
des-d
des-d...
|
NULL
|
|
51731
|
1119
|
67
|
2026-04-20T06:19:50.325203+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-20/1776 /Users/lukas/.screenpipe/data/data/2026-04-20/1776665990325_m2.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (32)
Pull requests
(
32
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (28)
Security and quality
(
28
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
32 Open
32 Open
10,900 Closed
10,900 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
11 / 12 checks OK
#11989 opened
3 days ago
by
yalokin-jiminny
yalokin-jiminny
3 comments
3
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
12 / 12 checks OK
#11988 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
12 / 12 checks OK
#11987 opened
3 days ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
12 / 13 checks OK
#11986 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
3 comments
3
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
12 / 12 checks OK
#11984 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
1 comment
1
JY-9712 | change nudges schema
JY-9712 | change nudges schema
JY-9712 | change nudges schema
8 / 10 checks OK
#11983 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
21 / 21 checks OK
#11981 opened
4 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
5 comments
5
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
12 / 12 checks OK
#11980 opened
4 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
8 comments
8
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
12 / 12 checks OK
#11976 opened
4 days ago
by
yalokin-jiminny
yalokin-jiminny
•
Review required before merging
Review required
5 comments
5
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
8 / 10 checks OK
#11975 opened
4 days ago
by
github-actions
github-actions
bot
•
Review required before merging
Review required
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
8 / 10 checks OK
#11972 opened
5 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Draft
Draft
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
12 / 13 checks OK
#11970 opened
5 days ago
by
github-actions
github-actions
bot
•
3 review approvals
Approved
3 comments
3
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
7 / 11 checks OK
#11955 opened
last week
by
jamesgraham
jamesgraham
•
1 review approval
Approved
8 tasks
Fix fontawesome download issues
Fix fontawesome download issues
Fix fontawesome download issues
10 / 12 checks OK
#11895 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
5 comments
5
Ask Jiminny Reports
Ask Jiminny Reports
Ask Jiminny Reports
22 / 22 checks OK
#11894 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
6 comments
6
Jy 20405 zapier actions
Jy 20405 zapier actions
Jy 20405 zapier actions
11 / 12 checks OK
#11868 opened
3 weeks ago
by
jamesgraham
jamesgraham
•
Review required before merging
Review required
8 comments
8
Oxc
Oxc
Oxc
12 / 13 checks OK
#11824 opened...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.0518755,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.06304868,"width":0.10106383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.08459697,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.09577015,"width":0.19963431,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.11731844,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.12849163,"width":0.15525267,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":4,"bounds":{"left":0.0,"top":0.15003991,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.16121309,"width":0.06981383,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.18276137,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.19393456,"width":0.04537899,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.18994413,"width":0.007978723,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.21707901,"width":0.07413564,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"bounds":{"left":0.07962101,"top":0.047885075,"width":0.0003324468,"height":0.0007980846},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"bounds":{"left":0.07962101,"top":0.049481247,"width":0.0029920214,"height":0.21468475},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"bounds":{"left":0.08494016,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"bounds":{"left":0.099567816,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"bounds":{"left":0.112865694,"top":0.060654428,"width":0.018949468,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"bounds":{"left":0.11486037,"top":0.066640064,"width":0.014960106,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"bounds":{"left":0.13680187,"top":0.060654428,"width":0.017785905,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"bounds":{"left":0.13879654,"top":0.066640064,"width":0.008477394,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"bounds":{"left":0.81698805,"top":0.060654428,"width":0.06565824,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"bounds":{"left":0.82928854,"top":0.066640064,"width":0.011801862,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"bounds":{"left":0.8424202,"top":0.06823623,"width":0.002493351,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"bounds":{"left":0.84640956,"top":0.066640064,"width":0.021276595,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"bounds":{"left":0.88464093,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"bounds":{"left":0.8949468,"top":0.060654428,"width":0.008643617,"height":0.025538707},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"bounds":{"left":0.9115692,"top":0.060654428,"width":0.01662234,"height":0.025538707},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Issues(g then i)","depth":9,"bounds":{"left":0.93085104,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Pull requests","depth":9,"bounds":{"left":0.94414896,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Repositories","depth":9,"bounds":{"left":0.9574468,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"bounds":{"left":0.97074467,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"bounds":{"left":0.9840425,"top":0.060654428,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"bounds":{"left":0.079288565,"top":0.04708699,"width":0.0003324468,"height":0.0007980846},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"bounds":{"left":0.079288565,"top":0.04988029,"width":0.0787899,"height":0.023144454},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"bounds":{"left":0.08494016,"top":0.09537111,"width":0.025099734,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"bounds":{"left":0.095744684,"top":0.10175578,"width":0.011469414,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (32)","depth":12,"bounds":{"left":0.11269947,"top":0.09537111,"width":0.05501995,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"bounds":{"left":0.12333777,"top":0.10175578,"width":0.02925532,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.15525267,"top":0.10973663,"width":0.0029920214,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"32","depth":14,"bounds":{"left":0.15824468,"top":0.10973663,"width":0.0056515955,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.16389628,"top":0.10973663,"width":0.0016622341,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"bounds":{"left":0.17037898,"top":0.09537111,"width":0.029089095,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"bounds":{"left":0.18134974,"top":0.10175578,"width":0.01512633,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"bounds":{"left":0.20212767,"top":0.09537111,"width":0.03025266,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"bounds":{"left":0.21326463,"top":0.10175578,"width":0.015957447,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"bounds":{"left":0.23503989,"top":0.09537111,"width":0.022938829,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"bounds":{"left":0.24601063,"top":0.10175578,"width":0.009142287,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality (28)","depth":12,"bounds":{"left":0.2606383,"top":0.09537111,"width":0.070644945,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"bounds":{"left":0.27244017,"top":0.10175578,"width":0.04255319,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"bounds":{"left":0.31881648,"top":0.10973663,"width":0.0029920214,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"28","depth":14,"bounds":{"left":0.32180852,"top":0.10973663,"width":0.0056515955,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"bounds":{"left":0.3274601,"top":0.10973663,"width":0.0018284575,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"bounds":{"left":0.33394283,"top":0.09537111,"width":0.03125,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"bounds":{"left":0.34524602,"top":0.10175578,"width":0.016788565,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"bounds":{"left":0.3678524,"top":0.09537111,"width":0.032081116,"height":0.026336791},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"bounds":{"left":0.37898937,"top":0.10175578,"width":0.017785905,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"bounds":{"left":0.09325133,"top":0.1396648,"width":0.0003324468,"height":0.016759777},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"bounds":{"left":0.09325133,"top":0.14126097,"width":0.039228722,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"bounds":{"left":0.09325133,"top":0.14126097,"width":0.2159242,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"bounds":{"left":0.30917552,"top":0.14126097,"width":0.04055851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"bounds":{"left":0.30917552,"top":0.14126097,"width":0.04055851,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"bounds":{"left":0.34973404,"top":0.14126097,"width":0.08261303,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"bounds":{"left":0.4323471,"top":0.14126097,"width":0.05219415,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"bounds":{"left":0.4323471,"top":0.14126097,"width":0.05219415,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"bounds":{"left":0.48454124,"top":0.14126097,"width":0.0013297872,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"bounds":{"left":0.98636967,"top":0.1348763,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"bounds":{"left":0.33776596,"top":0.18754987,"width":0.0003324468,"height":0.0007980846},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"bounds":{"left":0.33776596,"top":0.1915403,"width":0.04488032,"height":0.1452514},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"bounds":{"left":0.33776596,"top":0.18754987,"width":0.027426861,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Filters","depth":13,"bounds":{"left":0.34208778,"top":0.19353552,"width":0.013464096,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:pr is:open","depth":11,"bounds":{"left":0.3648604,"top":0.18754987,"width":0.23105054,"height":0.025538707},"value":"is:pr is:open","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"bounds":{"left":0.60123,"top":0.18754987,"width":0.043218084,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"bounds":{"left":0.6122008,"top":0.19353552,"width":0.016954787,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"bounds":{"left":0.6314827,"top":0.19513169,"width":0.004986702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"bounds":{"left":0.6441157,"top":0.18754987,"width":0.049534574,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"bounds":{"left":0.65508646,"top":0.19353552,"width":0.026263298,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.68367684,"top":0.19513169,"width":0.0019946808,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"bounds":{"left":0.69630986,"top":0.18754987,"width":0.045711435,"height":0.025538707},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"bounds":{"left":0.7006317,"top":0.19353552,"width":0.03706782,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"bounds":{"left":0.34341756,"top":0.24181964,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"32 Open","depth":11,"bounds":{"left":0.35339096,"top":0.23942538,"width":0.026928192,"height":0.016759777},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"32 Open","depth":12,"bounds":{"left":0.3600399,"top":0.24102154,"width":0.020279255,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"10,900 Closed","depth":11,"bounds":{"left":0.3849734,"top":0.23942538,"width":0.03873005,"height":0.016759777},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"10,900 Closed","depth":12,"bounds":{"left":0.39162233,"top":0.24102154,"width":0.032081116,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"bounds":{"left":0.52925533,"top":0.23942538,"width":0.018284574,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Author","depth":12,"bounds":{"left":0.52925533,"top":0.24102154,"width":0.015625,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"bounds":{"left":0.5581782,"top":0.23942538,"width":0.015625,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Label","depth":12,"bounds":{"left":0.5581782,"top":0.24102154,"width":0.012965426,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","depth":12,"bounds":{"left":0.5844415,"top":0.23942538,"width":0.02144282,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Projects","depth":13,"bounds":{"left":0.5844415,"top":0.24102154,"width":0.018783245,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","depth":12,"bounds":{"left":0.6178524,"top":0.23942538,"width":0.027260639,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Milestones","depth":13,"bounds":{"left":0.6178524,"top":0.24102154,"width":0.024601065,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","depth":12,"bounds":{"left":0.6570811,"top":0.23942538,"width":0.02144282,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reviews","depth":13,"bounds":{"left":0.6570811,"top":0.24102154,"width":0.018783245,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"bounds":{"left":0.68916225,"top":0.23942538,"width":0.0234375,"height":0.016759777},"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"bounds":{"left":0.68916225,"top":0.24102154,"width":0.020777926,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"bounds":{"left":0.72323805,"top":0.23942538,"width":0.013131649,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Sort","depth":12,"bounds":{"left":0.72323805,"top":0.24102154,"width":0.009142287,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"bounds":{"left":0.3380984,"top":0.2697526,"width":0.0003324468,"height":0.0007980846},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"bounds":{"left":0.3380984,"top":0.2725459,"width":0.03174867,"height":0.08060654},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":12,"bounds":{"left":0.34341756,"top":0.2793296,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":12,"bounds":{"left":0.36136967,"top":0.2793296,"width":0.11619016,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":13,"bounds":{"left":0.36136967,"top":0.2793296,"width":0.11619016,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"bounds":{"left":0.4788896,"top":0.27693537,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11989 opened","depth":13,"bounds":{"left":0.36136967,"top":0.3008779,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"bounds":{"left":0.39145613,"top":0.3008779,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41206783,"top":0.3008779,"width":0.0066489363,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":13,"bounds":{"left":0.41871676,"top":0.3008779,"width":0.02825798,"height":0.011971269},"help_text":"Open pull requests created by yalokin-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":14,"bounds":{"left":0.41871676,"top":0.3008779,"width":0.02825798,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"bounds":{"left":0.72706115,"top":0.27853152,"width":0.00930851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"bounds":{"left":0.7337101,"top":0.2801277,"width":0.0026595744,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20698 handle failed field sync on playbook import activity types","depth":12,"bounds":{"left":0.34341756,"top":0.33000797,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20698 handle failed field sync on playbook import activity types","depth":12,"bounds":{"left":0.36136967,"top":0.32960895,"width":0.17087767,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types","depth":13,"bounds":{"left":0.36136967,"top":0.32960895,"width":0.17087767,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"bounds":{"left":0.53357714,"top":0.32761374,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11988 opened","depth":13,"bounds":{"left":0.36136967,"top":0.35115722,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"bounds":{"left":0.39145613,"top":0.35115722,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41206783,"top":0.35115722,"width":0.0066489363,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.41871676,"top":0.35115722,"width":0.015458777,"height":0.011971269},"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.41871676,"top":0.35115722,"width":0.015458777,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.43550533,"top":0.35115722,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.43849733,"top":0.35115722,"width":0.03025266,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.43849733,"top":0.35115722,"width":0.03025266,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.72772604,"top":0.3292099,"width":0.008643617,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.734375,"top":0.33080608,"width":0.0019946808,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20695: Handle No raw transcript","depth":12,"bounds":{"left":0.34341756,"top":0.38028732,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20695: Handle No raw transcript","depth":12,"bounds":{"left":0.36136967,"top":0.38028732,"width":0.09158909,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20695: Handle No raw transcript","depth":13,"bounds":{"left":0.36136967,"top":0.38028732,"width":0.09158909,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"bounds":{"left":0.45428857,"top":0.37789306,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11987 opened","depth":13,"bounds":{"left":0.36136967,"top":0.4018356,"width":0.029920213,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"bounds":{"left":0.3912899,"top":0.4018356,"width":0.02044548,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.4117354,"top":0.4018356,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"mihailmihaylovjiminny","depth":13,"bounds":{"left":0.41855052,"top":0.4018356,"width":0.040724736,"height":0.011971269},"help_text":"Open pull requests created by mihailmihaylovjiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"mihailmihaylovjiminny","depth":14,"bounds":{"left":0.41855052,"top":0.4018356,"width":0.040724736,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.46060506,"top":0.4018356,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.4635971,"top":0.4018356,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.4635971,"top":0.4018356,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.72772604,"top":0.3794892,"width":0.008643617,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.734375,"top":0.3810854,"width":0.0019946808,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20692 change confirmation parameter","depth":12,"bounds":{"left":0.34341756,"top":0.4309657,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20692 change confirmation parameter","depth":12,"bounds":{"left":0.36136967,"top":0.4309657,"width":0.10638298,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter","depth":13,"bounds":{"left":0.36136967,"top":0.4309657,"width":0.10638298,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"bounds":{"left":0.46908244,"top":0.42857143,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11986 opened","depth":13,"bounds":{"left":0.36136967,"top":0.45251396,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"bounds":{"left":0.39145613,"top":0.45251396,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41206783,"top":0.45251396,"width":0.0066489363,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"bounds":{"left":0.41871676,"top":0.45251396,"width":0.015458777,"height":0.011971269},"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"bounds":{"left":0.41871676,"top":0.45251396,"width":0.015458777,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.43550533,"top":0.45251396,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.43849733,"top":0.45251396,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.43849733,"top":0.45251396,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"bounds":{"left":0.72706115,"top":0.4301676,"width":0.00930851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"bounds":{"left":0.7337101,"top":0.43176377,"width":0.0026595744,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Add Makefile shortcuts for environment toggle commands","depth":12,"bounds":{"left":0.34341756,"top":0.48164406,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Add Makefile shortcuts for environment toggle commands","depth":12,"bounds":{"left":0.36136967,"top":0.481245,"width":0.14660904,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add Makefile shortcuts for environment toggle commands","depth":13,"bounds":{"left":0.36136967,"top":0.481245,"width":0.14660904,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"bounds":{"left":0.5093085,"top":0.4792498,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11984 opened","depth":13,"bounds":{"left":0.36136967,"top":0.5027933,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"bounds":{"left":0.39145613,"top":0.5027933,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41206783,"top":0.5027933,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"bounds":{"left":0.41888297,"top":0.5027933,"width":0.030585106,"height":0.011971269},"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"bounds":{"left":0.41888297,"top":0.5027933,"width":0.030585106,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.4507979,"top":0.5027933,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.4537899,"top":0.5027933,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.4537899,"top":0.5027933,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"bounds":{"left":0.72772604,"top":0.48084596,"width":0.008643617,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"bounds":{"left":0.734375,"top":0.48244214,"width":0.0019946808,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-9712 | change nudges schema","depth":12,"bounds":{"left":0.34341756,"top":0.5319234,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-9712 | change nudges schema","depth":12,"bounds":{"left":0.36136967,"top":0.5319234,"width":0.084773935,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-9712 | change nudges schema","depth":13,"bounds":{"left":0.36136967,"top":0.5319234,"width":0.084773935,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"bounds":{"left":0.4474734,"top":0.52952915,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11983 opened","depth":13,"bounds":{"left":0.36136967,"top":0.5534717,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"bounds":{"left":0.39145613,"top":0.5534717,"width":0.02044548,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.4119016,"top":0.5534717,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"bounds":{"left":0.41871676,"top":0.5534717,"width":0.030751329,"height":0.011971269},"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"bounds":{"left":0.41871676,"top":0.5534717,"width":0.030751329,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.4507979,"top":0.5534717,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.4537899,"top":0.5534717,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.4537899,"top":0.5534717,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-9712 | Nuges to expire after one year","depth":12,"bounds":{"left":0.34341756,"top":0.5826017,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-9712 | Nuges to expire after one year","depth":12,"bounds":{"left":0.36136967,"top":0.58220273,"width":0.101230055,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-9712 | Nuges to expire after one year","depth":13,"bounds":{"left":0.36136967,"top":0.58220273,"width":0.101230055,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"21 / 21 checks OK","depth":13,"bounds":{"left":0.46392953,"top":0.5802075,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11981 opened","depth":13,"bounds":{"left":0.36136967,"top":0.603751,"width":0.029421542,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"bounds":{"left":0.39079124,"top":0.603751,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.4114029,"top":0.603751,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"bounds":{"left":0.41821808,"top":0.603751,"width":0.030585106,"height":0.011971269},"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"bounds":{"left":0.41821808,"top":0.603751,"width":0.030585106,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.45013297,"top":0.603751,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.453125,"top":0.603751,"width":0.03025266,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.453125,"top":0.603751,"width":0.03025266,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"bounds":{"left":0.72706115,"top":0.5818037,"width":0.00930851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"bounds":{"left":0.7337101,"top":0.58339983,"width":0.0026595744,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20541 remove crm contract method","depth":12,"bounds":{"left":0.34341756,"top":0.6328811,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20541 remove crm contract method","depth":12,"bounds":{"left":0.36136967,"top":0.6328811,"width":0.09823803,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20541 remove crm contract method","depth":13,"bounds":{"left":0.36136967,"top":0.6328811,"width":0.09823803,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"bounds":{"left":0.46077126,"top":0.63048685,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11980 opened","depth":13,"bounds":{"left":0.36136967,"top":0.6544294,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"bounds":{"left":0.39145613,"top":0.6544294,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41206783,"top":0.6544294,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":13,"bounds":{"left":0.41888297,"top":0.6544294,"width":0.024933511,"height":0.011971269},"help_text":"Open pull requests created by Vasil-Jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":14,"bounds":{"left":0.41888297,"top":0.6544294,"width":0.024933511,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.44514626,"top":0.6544294,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.4481383,"top":0.6544294,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.4481383,"top":0.6544294,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"8 comments","depth":12,"bounds":{"left":0.726895,"top":0.632083,"width":0.009474734,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"8","depth":13,"bounds":{"left":0.7335439,"top":0.63367915,"width":0.0028257978,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20553 | Improve crm-sync delays","depth":12,"bounds":{"left":0.34341756,"top":0.6835595,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20553 | Improve crm-sync delays","depth":12,"bounds":{"left":0.36136967,"top":0.6835595,"width":0.09325133,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20553 | Improve crm-sync delays","depth":13,"bounds":{"left":0.36136967,"top":0.6835595,"width":0.09325133,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"bounds":{"left":0.4559508,"top":0.6811652,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11976 opened","depth":13,"bounds":{"left":0.36136967,"top":0.70510775,"width":0.029753989,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"bounds":{"left":0.39112368,"top":0.70510775,"width":0.02044548,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41156915,"top":0.70510775,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":13,"bounds":{"left":0.4183843,"top":0.70510775,"width":0.02825798,"height":0.011971269},"help_text":"Open pull requests created by yalokin-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":14,"bounds":{"left":0.4183843,"top":0.70510775,"width":0.02825798,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.4479721,"top":0.70510775,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.4509641,"top":0.70510775,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.4509641,"top":0.70510775,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"bounds":{"left":0.72706115,"top":0.6827614,"width":0.00930851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"bounds":{"left":0.7337101,"top":0.6843575,"width":0.0026595744,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"fix(security): npm dependency updates – 2026-04-16","depth":12,"bounds":{"left":0.34341756,"top":0.73423785,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"fix(security): npm dependency updates – 2026-04-16","depth":12,"bounds":{"left":0.36136967,"top":0.7338388,"width":0.13663563,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): npm dependency updates – 2026-04-16","depth":13,"bounds":{"left":0.36136967,"top":0.7338388,"width":0.13663563,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"bounds":{"left":0.4993351,"top":0.7318436,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11975 opened","depth":13,"bounds":{"left":0.36136967,"top":0.7561852,"width":0.029587766,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"bounds":{"left":0.39095744,"top":0.7561852,"width":0.020611702,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41156915,"top":0.7561852,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"github-actions","depth":13,"bounds":{"left":0.4183843,"top":0.7561852,"width":0.027593086,"height":0.011971269},"help_text":"Open pull requests created by github-actions[bot]","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"github-actions","depth":14,"bounds":{"left":0.4183843,"top":0.7561852,"width":0.027593086,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bot","depth":14,"bounds":{"left":0.44946808,"top":0.7561852,"width":0.0063164895,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.45944148,"top":0.75538707,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.46243352,"top":0.75538707,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.46243352,"top":0.75538707,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20541 cleanup stale tasks and events","depth":12,"bounds":{"left":0.34341756,"top":0.7861133,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20541 cleanup stale tasks and events","depth":12,"bounds":{"left":0.36136967,"top":0.7861133,"width":0.1022274,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20541 cleanup stale tasks and events","depth":13,"bounds":{"left":0.36136967,"top":0.7861133,"width":0.1022274,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"bounds":{"left":0.46476063,"top":0.78371906,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11972 opened","depth":13,"bounds":{"left":0.36136967,"top":0.8076616,"width":0.029587766,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 days ago","depth":14,"bounds":{"left":0.39095744,"top":0.8076616,"width":0.02044548,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.4114029,"top":0.8076616,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":13,"bounds":{"left":0.41821808,"top":0.8076616,"width":0.024933511,"height":0.011971269},"help_text":"Open pull requests created by Vasil-Jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":14,"bounds":{"left":0.41821808,"top":0.8076616,"width":0.024933511,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.44448137,"top":0.8076616,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"bounds":{"left":0.4474734,"top":0.8076616,"width":0.009640957,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"bounds":{"left":0.4474734,"top":0.8076616,"width":0.009640957,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"fix(security): composer dependency updates – 2026-04-15","depth":12,"bounds":{"left":0.34341756,"top":0.8367917,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"fix(security): composer dependency updates – 2026-04-15","depth":12,"bounds":{"left":0.36136967,"top":0.8367917,"width":0.1505984,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15","depth":13,"bounds":{"left":0.36136967,"top":0.8367917,"width":0.1505984,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"bounds":{"left":0.51329786,"top":0.83439744,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11970 opened","depth":13,"bounds":{"left":0.36136967,"top":0.8591381,"width":0.029753989,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 days ago","depth":14,"bounds":{"left":0.39112368,"top":0.8591381,"width":0.02044548,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41156915,"top":0.8591381,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"github-actions","depth":13,"bounds":{"left":0.4183843,"top":0.8591381,"width":0.027426861,"height":0.011971269},"help_text":"Open pull requests created by github-actions[bot]","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"github-actions","depth":14,"bounds":{"left":0.4183843,"top":0.8591381,"width":0.027426861,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bot","depth":14,"bounds":{"left":0.44930187,"top":0.8591381,"width":0.006482713,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.45944148,"top":0.85833997,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 review approvals","depth":13,"bounds":{"left":0.46243352,"top":0.85833997,"width":0.018118352,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"bounds":{"left":0.46243352,"top":0.85833997,"width":0.018118352,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"bounds":{"left":0.72706115,"top":0.8359936,"width":0.00930851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"bounds":{"left":0.7337101,"top":0.8375898,"width":0.0026595744,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20663 Add Rockeed partner","depth":12,"bounds":{"left":0.34341756,"top":0.8890662,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20663 Add Rockeed partner","depth":12,"bounds":{"left":0.36136967,"top":0.8886672,"width":0.08028591,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20663 Add Rockeed partner","depth":13,"bounds":{"left":0.36136967,"top":0.8886672,"width":0.08028591,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"7 / 11 checks OK","depth":13,"bounds":{"left":0.4429854,"top":0.88667196,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11955 opened","depth":13,"bounds":{"left":0.36136967,"top":0.9102155,"width":0.029920213,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"last week","depth":14,"bounds":{"left":0.3912899,"top":0.9102155,"width":0.01761968,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.4089096,"top":0.9102155,"width":0.0068151597,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"jamesgraham","depth":13,"bounds":{"left":0.41572472,"top":0.9102155,"width":0.025099734,"height":0.011971269},"help_text":"Open pull requests created by jamesgraham","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jamesgraham","depth":14,"bounds":{"left":0.41572472,"top":0.9102155,"width":0.025099734,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.44215426,"top":0.9102155,"width":0.0031582448,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"bounds":{"left":0.4453125,"top":0.9102155,"width":0.017952127,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"bounds":{"left":0.4453125,"top":0.9102155,"width":0.017952127,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8 tasks","depth":14,"bounds":{"left":0.47257313,"top":0.9102155,"width":0.013630319,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Fix fontawesome download issues","depth":12,"bounds":{"left":0.34341756,"top":0.9393456,"width":0.004654255,"height":0.011173184},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Fix fontawesome download issues","depth":12,"bounds":{"left":0.36136967,"top":0.9393456,"width":0.0859375,"height":0.015163607},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fix fontawesome download issues","depth":13,"bounds":{"left":0.36136967,"top":0.9393456,"width":0.0859375,"height":0.015163607},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"10 / 12 checks OK","depth":13,"bounds":{"left":0.44863698,"top":0.93695134,"width":0.005319149,"height":0.016759777},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11895 opened","depth":13,"bounds":{"left":0.36136967,"top":0.96089387,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 weeks ago","depth":14,"bounds":{"left":0.39145613,"top":0.96089387,"width":0.0234375,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41489363,"top":0.96089387,"width":0.0066489363,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolay-yankov","depth":13,"bounds":{"left":0.42154256,"top":0.96089387,"width":0.028091755,"height":0.011971269},"help_text":"Open pull requests created by nikolay-yankov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolay-yankov","depth":14,"bounds":{"left":0.42154256,"top":0.96089387,"width":0.028091755,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.4509641,"top":0.96089387,"width":0.0029920214,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.45395613,"top":0.96089387,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.45395613,"top":0.96089387,"width":0.030086435,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"bounds":{"left":0.72706115,"top":0.9385475,"width":0.00930851,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"bounds":{"left":0.7337101,"top":0.94014364,"width":0.0026595744,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Ask Jiminny Reports","depth":12,"bounds":{"left":0.34341756,"top":0.990024,"width":0.004654255,"height":0.009976029},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Ask Jiminny Reports","depth":12,"bounds":{"left":0.36136967,"top":0.990024,"width":0.051695477,"height":0.009976029},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny Reports","depth":13,"bounds":{"left":0.36136967,"top":0.990024,"width":0.051695477,"height":0.009976029},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 22 checks OK","depth":13,"bounds":{"left":0.41439494,"top":0.9876297,"width":0.005319149,"height":0.012370288},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11894 opened","depth":13,"bounds":{"left":0.36136967,"top":1.0,"width":0.030086435,"height":-0.011572242},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 weeks ago","depth":14,"bounds":{"left":0.39145613,"top":1.0,"width":0.0234375,"height":-0.011572242},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41489363,"top":1.0,"width":0.0068151597,"height":-0.011572242},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolay-yankov","depth":13,"bounds":{"left":0.42170876,"top":1.0,"width":0.027925532,"height":-0.011572242},"help_text":"Open pull requests created by nikolay-yankov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolay-yankov","depth":14,"bounds":{"left":0.42170876,"top":1.0,"width":0.027925532,"height":-0.011572242},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.4509641,"top":1.0,"width":0.0029920214,"height":-0.011572242},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.45395613,"top":1.0,"width":0.030086435,"height":-0.011572242},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.45395613,"top":1.0,"width":0.030086435,"height":-0.011572242},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"6 comments","depth":12,"bounds":{"left":0.72706115,"top":0.98922586,"width":0.00930851,"height":0.010774136},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"6","depth":13,"bounds":{"left":0.7335439,"top":0.990822,"width":0.0028257978,"height":0.009177983},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20405 zapier actions","depth":12,"bounds":{"left":0.34341756,"top":1.0,"width":0.004654255,"height":-0.040702343},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20405 zapier actions","depth":12,"bounds":{"left":0.36136967,"top":1.0,"width":0.061170213,"height":-0.04030323},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20405 zapier actions","depth":13,"bounds":{"left":0.36136967,"top":1.0,"width":0.061170213,"height":-0.04030323},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"bounds":{"left":0.42370346,"top":1.0,"width":0.005319149,"height":-0.038308024},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11868 opened","depth":13,"bounds":{"left":0.36136967,"top":1.0,"width":0.030086435,"height":-0.0618515},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 weeks ago","depth":14,"bounds":{"left":0.39145613,"top":1.0,"width":0.023603724,"height":-0.0618515},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.41505983,"top":1.0,"width":0.0066489363,"height":-0.0618515},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"jamesgraham","depth":13,"bounds":{"left":0.42170876,"top":1.0,"width":0.025265958,"height":-0.0618515},"help_text":"Open pull requests created by jamesgraham","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jamesgraham","depth":14,"bounds":{"left":0.42170876,"top":1.0,"width":0.025265958,"height":-0.0618515},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.44830453,"top":1.0,"width":0.0029920214,"height":-0.0618515},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.45129654,"top":1.0,"width":0.030086435,"height":-0.0618515},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.45129654,"top":1.0,"width":0.030086435,"height":-0.0618515},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"8 comments","depth":12,"bounds":{"left":0.726895,"top":1.0,"width":0.009474734,"height":-0.039904237},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"8","depth":13,"bounds":{"left":0.7335439,"top":1.0,"width":0.0028257978,"height":-0.04150045},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Oxc","depth":12,"bounds":{"left":0.34341756,"top":1.0,"width":0.004654255,"height":-0.0909816},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Oxc","depth":12,"bounds":{"left":0.36136967,"top":1.0,"width":0.009640957,"height":-0.0909816},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Oxc","depth":13,"bounds":{"left":0.36136967,"top":1.0,"width":0.009640957,"height":-0.0909816},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"bounds":{"left":0.3723404,"top":1.0,"width":0.005319149,"height":-0.0885874},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11824 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-1743219133383934967
|
8954691543051766530
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (32)
Pull requests
(
32
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (28)
Security and quality
(
28
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
32 Open
32 Open
10,900 Closed
10,900 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
11 / 12 checks OK
#11989 opened
3 days ago
by
yalokin-jiminny
yalokin-jiminny
3 comments
3
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
12 / 12 checks OK
#11988 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
12 / 12 checks OK
#11987 opened
3 days ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
12 / 13 checks OK
#11986 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
3 comments
3
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
12 / 12 checks OK
#11984 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
1 comment
1
JY-9712 | change nudges schema
JY-9712 | change nudges schema
JY-9712 | change nudges schema
8 / 10 checks OK
#11983 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
21 / 21 checks OK
#11981 opened
4 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
5 comments
5
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
12 / 12 checks OK
#11980 opened
4 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
8 comments
8
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
12 / 12 checks OK
#11976 opened
4 days ago
by
yalokin-jiminny
yalokin-jiminny
•
Review required before merging
Review required
5 comments
5
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
8 / 10 checks OK
#11975 opened
4 days ago
by
github-actions
github-actions
bot
•
Review required before merging
Review required
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
8 / 10 checks OK
#11972 opened
5 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Draft
Draft
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
12 / 13 checks OK
#11970 opened
5 days ago
by
github-actions
github-actions
bot
•
3 review approvals
Approved
3 comments
3
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
7 / 11 checks OK
#11955 opened
last week
by
jamesgraham
jamesgraham
•
1 review approval
Approved
8 tasks
Fix fontawesome download issues
Fix fontawesome download issues
Fix fontawesome download issues
10 / 12 checks OK
#11895 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
5 comments
5
Ask Jiminny Reports
Ask Jiminny Reports
Ask Jiminny Reports
22 / 22 checks OK
#11894 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
6 comments
6
Jy 20405 zapier actions
Jy 20405 zapier actions
Jy 20405 zapier actions
11 / 12 checks OK
#11868 opened
3 weeks ago
by
jamesgraham
jamesgraham
•
Review required before merging
Review required
8 comments
8
Oxc
Oxc
Oxc
12 / 13 checks OK
#11824 opened...
|
51729
|
|
51733
|
1118
|
48
|
2026-04-20T06:19:51.158916+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-20/1776 /Users/lukas/.screenpipe/data/data/2026-04-20/1776665991158_m1.jpg...
|
Firefox
|
Pull requests · jiminny/app — Work
|
1
|
github.com/jiminny/app/pulls
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Close bookmarks (⌘B)
Bookmarks
Bookmarks
Close sidebar
Search bookmarks
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (32)
Pull requests
(
32
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (28)
Security and quality
(
28
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
32 Open
32 Open
10,900 Closed
10,900 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
11 / 12 checks OK
#11989 opened
3 days ago
by
yalokin-jiminny
yalokin-jiminny
3 comments
3
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
12 / 12 checks OK
#11988 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
12 / 12 checks OK
#11987 opened
3 days ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
12 / 13 checks OK
#11986 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
3 comments
3
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
12 / 12 checks OK
#11984 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
1 comment
1
JY-9712 | change nudges schema
JY-9712 | change nudges schema
JY-9712 | change nudges schema
8 / 10 checks OK
#11983 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
21 / 21 checks OK
#11981 opened
4 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
5 comments
5
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
12 / 12 checks OK
#11980 opened
4 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
8 comments
8
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
12 / 12 checks OK
#11976 opened
4 days ago
by
yalokin-jiminny
yalokin-jiminny
•
Review required before merging
Review required
5 comments
5
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
8 / 10 checks OK
#11975 opened
4 days ago
by
github-actions
github-actions
bot
•
Review required before merging
Review required
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
8 / 10 checks OK
#11972 opened
5 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Draft
Draft
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
12 / 13 checks OK
#11970 opened
5 days ago
by
github-actions
github-actions
bot
•
3 review approvals
Approved
3 comments
3
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
7 / 11 checks OK
#11955 opened
last week
by
jamesgraham
jamesgraham
•
1 review approval
Approved
8 tasks
Fix fontawesome download issues
Fix fontawesome download issues
Fix fontawesome download issues
10 / 12 checks OK
#11895 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
5 comments
5
Ask Jiminny Reports
Ask Jiminny Reports
Ask Jiminny Reports
22 / 22 checks OK
#11894 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
6 comments
6
Jy 20405 zapier actions
Jy 20405 zapier actions
Jy 20405 zapier actions
11 / 12 checks OK
#11868 opened
3 weeks ago
by
jamesgraham
jamesgraham
•
Review required before merging
Review required
8 comments
8...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20543] AJ Reports > Tracking - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pull requests · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Pull requests · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Bookmarks","depth":5,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bookmarks","depth":6,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close sidebar","depth":6,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXTextField","text":"Search bookmarks","depth":7,"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Issues(g then i)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Pull requests","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Repositories","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (32)","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"32","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality (28)","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"28","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Pull requests: jiminny/app","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests: jiminny/app","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Filters","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Filters","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"is:pr is:open","depth":11,"value":"is:pr is:open","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Labels 67","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Labels","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"67","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Milestones 1","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Milestones","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"New pull request","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New pull request","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Select all issues","depth":11,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"32 Open","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"32 Open","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"10,900 Closed","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"10,900 Closed","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Author","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Author","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Label","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Label","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Projects","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Projects","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Milestones","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Milestones","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Reviews","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Reviews","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Assignee","depth":11,"help_text":"Assignees","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Assignee","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sort","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Sort","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Pull requests list","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pull requests list","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11989 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":13,"help_text":"Open pull requests created by yalokin-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20698 handle failed field sync on playbook import activity types","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20698 handle failed field sync on playbook import activity types","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11988 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20695: Handle No raw transcript","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20695: Handle No raw transcript","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20695: Handle No raw transcript","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11987 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"mihailmihaylovjiminny","depth":13,"help_text":"Open pull requests created by mihailmihaylovjiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"mihailmihaylovjiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20692 change confirmation parameter","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20692 change confirmation parameter","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20692 change confirmation parameter","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11986 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"LakyLak","depth":13,"help_text":"Open pull requests created by LakyLak","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"LakyLak","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Add Makefile shortcuts for environment toggle commands","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Add Makefile shortcuts for environment toggle commands","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add Makefile shortcuts for environment toggle commands","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11984 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 comment","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-9712 | change nudges schema","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-9712 | change nudges schema","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-9712 | change nudges schema","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11983 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-9712 | Nuges to expire after one year","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-9712 | Nuges to expire after one year","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-9712 | Nuges to expire after one year","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"21 / 21 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11981 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolaybiaivanov","depth":13,"help_text":"Open pull requests created by nikolaybiaivanov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolaybiaivanov","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20541 remove crm contract method","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20541 remove crm contract method","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20541 remove crm contract method","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11980 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":13,"help_text":"Open pull requests created by Vasil-Jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"8 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"8","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20553 | Improve crm-sync delays","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20553 | Improve crm-sync delays","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20553 | Improve crm-sync delays","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 12 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11976 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":13,"help_text":"Open pull requests created by yalokin-jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"fix(security): npm dependency updates – 2026-04-16","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"fix(security): npm dependency updates – 2026-04-16","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): npm dependency updates – 2026-04-16","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11975 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"github-actions","depth":13,"help_text":"Open pull requests created by github-actions[bot]","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"github-actions","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bot","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20541 cleanup stale tasks and events","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20541 cleanup stale tasks and events","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20541 cleanup stale tasks and events","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"8 / 10 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11972 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Vasil-Jiminny","depth":13,"help_text":"Open pull requests created by Vasil-Jiminny","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Vasil-Jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Draft","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Draft","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"fix(security): composer dependency updates – 2026-04-15","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"fix(security): composer dependency updates – 2026-04-15","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix(security): composer dependency updates – 2026-04-15","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"12 / 13 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11970 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5 days ago","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"github-actions","depth":13,"help_text":"Open pull requests created by github-actions[bot]","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"github-actions","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bot","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 review approvals","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3 comments","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"JY-20663 Add Rockeed partner","depth":12,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20663 Add Rockeed partner","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20663 Add Rockeed partner","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"7 / 11 checks OK","depth":13,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11955 opened","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"last week","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"jamesgraham","depth":13,"help_text":"Open pull requests created by jamesgraham","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jamesgraham","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1 review approval","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Approved","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8 tasks","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Fix fontawesome download issues","depth":12,"bounds":{"left":0.27395833,"top":0.0,"width":0.009722223,"height":0.015555556},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Fix fontawesome download issues","depth":12,"bounds":{"left":0.31145832,"top":0.0,"width":0.17951389,"height":0.02111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fix fontawesome download issues","depth":13,"bounds":{"left":0.31145832,"top":0.0,"width":0.17951389,"height":0.02111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"10 / 12 checks OK","depth":13,"bounds":{"left":0.49375,"top":0.0,"width":0.011111111,"height":0.023333333},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11895 opened","depth":13,"bounds":{"left":0.31145832,"top":0.0,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 weeks ago","depth":14,"bounds":{"left":0.37430555,"top":0.0,"width":0.048958335,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.42326388,"top":0.0,"width":0.013888889,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolay-yankov","depth":13,"bounds":{"left":0.43715277,"top":0.0,"width":0.058680557,"height":0.016666668},"help_text":"Open pull requests created by nikolay-yankov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolay-yankov","depth":14,"bounds":{"left":0.43715277,"top":0.0,"width":0.058680557,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.49861112,"top":0.0,"width":0.00625,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.5048611,"top":0.0,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.5048611,"top":0.0,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5 comments","depth":12,"bounds":{"left":1.0,"top":0.0,"width":-0.075347185,"height":0.018888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5","depth":13,"bounds":{"left":1.0,"top":0.0,"width":-0.08923614,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Ask Jiminny Reports","depth":12,"bounds":{"left":0.27395833,"top":0.0,"width":0.009722223,"height":0.015555556},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Ask Jiminny Reports","depth":12,"bounds":{"left":0.31145832,"top":0.0,"width":0.10798611,"height":0.02111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny Reports","depth":13,"bounds":{"left":0.31145832,"top":0.0,"width":0.10798611,"height":0.02111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"22 / 22 checks OK","depth":13,"bounds":{"left":0.42222223,"top":0.0,"width":0.011111111,"height":0.023333333},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11894 opened","depth":13,"bounds":{"left":0.31145832,"top":0.016111111,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2 weeks ago","depth":14,"bounds":{"left":0.37430555,"top":0.016111111,"width":0.048958335,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.42326388,"top":0.016111111,"width":0.014236111,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"nikolay-yankov","depth":13,"bounds":{"left":0.4375,"top":0.016111111,"width":0.058333334,"height":0.016666668},"help_text":"Open pull requests created by nikolay-yankov","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"nikolay-yankov","depth":14,"bounds":{"left":0.4375,"top":0.016111111,"width":0.058333334,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.49861112,"top":0.016111111,"width":0.00625,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.5048611,"top":0.016111111,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.5048611,"top":0.016111111,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"6 comments","depth":12,"bounds":{"left":1.0,"top":0.0,"width":-0.075347185,"height":0.018888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"6","depth":13,"bounds":{"left":1.0,"top":0.0,"width":-0.08888888,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Jy 20405 zapier actions","depth":12,"bounds":{"left":0.27395833,"top":0.05666667,"width":0.009722223,"height":0.015555556},"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Jy 20405 zapier actions","depth":12,"bounds":{"left":0.31145832,"top":0.056111112,"width":0.12777779,"height":0.02111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 20405 zapier actions","depth":13,"bounds":{"left":0.31145832,"top":0.056111112,"width":0.12777779,"height":0.02111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"11 / 12 checks OK","depth":13,"bounds":{"left":0.44166666,"top":0.053333335,"width":0.011111111,"height":0.023333333},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"#11868 opened","depth":13,"bounds":{"left":0.31145832,"top":0.08611111,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 weeks ago","depth":14,"bounds":{"left":0.37430555,"top":0.08611111,"width":0.049305554,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":13,"bounds":{"left":0.4236111,"top":0.08611111,"width":0.013888889,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"jamesgraham","depth":13,"bounds":{"left":0.4375,"top":0.08611111,"width":0.05277778,"height":0.016666668},"help_text":"Open pull requests created by jamesgraham","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jamesgraham","depth":14,"bounds":{"left":0.4375,"top":0.08611111,"width":0.05277778,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":13,"bounds":{"left":0.49305555,"top":0.08611111,"width":0.00625,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review required before merging","depth":13,"bounds":{"left":0.49930555,"top":0.08611111,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review required","depth":14,"bounds":{"left":0.49930555,"top":0.08611111,"width":0.06284722,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"8 comments","depth":12,"bounds":{"left":1.0,"top":0.055555556,"width":-0.07500005,"height":0.018888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"8","depth":13,"bounds":{"left":1.0,"top":0.057777777,"width":-0.08888888,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
3890492897343301330
|
8954691543051766530
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
JY-20692 change confirmation parameter by LakyLak · Pull Request #11986 · jiminny/app
[JY-20543] AJ Reports > Tracking - Jira
[JY-20543] AJ Reports > Tracking - Jira
Pull requests · jiminny/app
Pull requests · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Close bookmarks (⌘B)
Bookmarks
Bookmarks
Close sidebar
Search bookmarks
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (32)
Pull requests
(
32
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (28)
Security and quality
(
28
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Pull requests: jiminny/app
Pull requests: jiminny/app
Filters
Filters
is:pr is:open
Labels 67
Labels
67
Milestones 1
Milestones
1
New pull request
New pull request
Select all issues
32 Open
32 Open
10,900 Closed
10,900 Closed
Author
Author
Label
Label
Projects
Projects
Milestones
Milestones
Reviews
Reviews
Assignee
Assignee
Sort
Sort
Pull requests list
Pull requests list
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
11 / 12 checks OK
#11989 opened
3 days ago
by
yalokin-jiminny
yalokin-jiminny
3 comments
3
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
JY-20698 handle failed field sync on playbook import activity types
12 / 12 checks OK
#11988 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
1 comment
1
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
JY-20695: Handle No raw transcript
12 / 12 checks OK
#11987 opened
3 days ago
by
mihailmihaylovjiminny
mihailmihaylovjiminny
•
Review required before merging
Review required
1 comment
1
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
JY-20692 change confirmation parameter
12 / 13 checks OK
#11986 opened
3 days ago
by
LakyLak
LakyLak
•
Review required before merging
Review required
3 comments
3
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
Add Makefile shortcuts for environment toggle commands
12 / 12 checks OK
#11984 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
1 comment
1
JY-9712 | change nudges schema
JY-9712 | change nudges schema
JY-9712 | change nudges schema
8 / 10 checks OK
#11983 opened
3 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
JY-9712 | Nuges to expire after one year
21 / 21 checks OK
#11981 opened
4 days ago
by
nikolaybiaivanov
nikolaybiaivanov
•
Review required before merging
Review required
5 comments
5
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
Jy 20541 remove crm contract method
12 / 12 checks OK
#11980 opened
4 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Review required before merging
Review required
8 comments
8
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
JY-20553 | Improve crm-sync delays
12 / 12 checks OK
#11976 opened
4 days ago
by
yalokin-jiminny
yalokin-jiminny
•
Review required before merging
Review required
5 comments
5
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
fix(security): npm dependency updates – 2026-04-16
8 / 10 checks OK
#11975 opened
4 days ago
by
github-actions
github-actions
bot
•
Review required before merging
Review required
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
Jy 20541 cleanup stale tasks and events
8 / 10 checks OK
#11972 opened
5 days ago
by
Vasil-Jiminny
Vasil-Jiminny
•
Draft
Draft
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
fix(security): composer dependency updates – 2026-04-15
12 / 13 checks OK
#11970 opened
5 days ago
by
github-actions
github-actions
bot
•
3 review approvals
Approved
3 comments
3
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
JY-20663 Add Rockeed partner
7 / 11 checks OK
#11955 opened
last week
by
jamesgraham
jamesgraham
•
1 review approval
Approved
8 tasks
Fix fontawesome download issues
Fix fontawesome download issues
Fix fontawesome download issues
10 / 12 checks OK
#11895 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
5 comments
5
Ask Jiminny Reports
Ask Jiminny Reports
Ask Jiminny Reports
22 / 22 checks OK
#11894 opened
2 weeks ago
by
nikolay-yankov
nikolay-yankov
•
Review required before merging
Review required
6 comments
6
Jy 20405 zapier actions
Jy 20405 zapier actions
Jy 20405 zapier actions
11 / 12 checks OK
#11868 opened
3 weeks ago
by
jamesgraham
jamesgraham
•
Review required before merging
Review required
8 comments
8...
|
51730
|