-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for Omni- and Service-Channel Settings and provide …
…access to presence status via Permission Sets (#658) - Adds the ability to enable the status-based capacity model for Omni-Channel - Adds the ability to configure the status-based capacity model for a specific Service Channel - Adds the ability to provide access to a presence status via Permission Sets (#564)
- Loading branch information
1 parent
dbd9cc0
commit 3155232
Showing
22 changed files
with
702 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import assert from 'assert'; | ||
import { OmniChannelSettings } from './index.js'; | ||
|
||
describe(OmniChannelSettings.name, function () { | ||
this.timeout('10m'); | ||
let plugin: OmniChannelSettings; | ||
before(() => { | ||
plugin = new OmniChannelSettings(global.bf); | ||
}); | ||
|
||
const configEnableStatusBasedCapacityModel = { | ||
enableStatusBasedCapacityModel: true | ||
}; | ||
const configDisableStatusBasedCapacityModel = { | ||
enableStatusBasedCapacityModel: false | ||
}; | ||
|
||
it('should enable status based capacity model', async () => { | ||
await plugin.run(configEnableStatusBasedCapacityModel); | ||
const res = await plugin.retrieve(); | ||
assert.deepStrictEqual(res, configEnableStatusBasedCapacityModel); | ||
}); | ||
|
||
it('should disable status based capacity model', async () => { | ||
await plugin.run(configDisableStatusBasedCapacityModel); | ||
const res = await plugin.retrieve(); | ||
assert.deepStrictEqual(res, configDisableStatusBasedCapacityModel); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { BrowserforcePlugin } from '../../plugin.js'; | ||
|
||
const PATHS = { | ||
BASE: 'omnichannel/settings.apexp' | ||
}; | ||
|
||
const SELECTORS = { | ||
SAVE_BUTTON: 'input[id$=":save"]', | ||
STATUS_CAPACITY_TOGGLE: 'input[id$=":toggleOmniStatusCapModelPref"]' | ||
}; | ||
|
||
type Config = { | ||
enableStatusBasedCapacityModel?: boolean; | ||
}; | ||
|
||
export class OmniChannelSettings extends BrowserforcePlugin { | ||
public async retrieve(definition?: Config): Promise<Config> { | ||
// Open the omni-channel setup page | ||
const page = await this.browserforce.openPage(PATHS.BASE); | ||
|
||
// Retrieve the service channel config | ||
await page.waitForSelector(SELECTORS.STATUS_CAPACITY_TOGGLE); | ||
const enableStatusBasedCapacityModel = await page.$eval(SELECTORS.STATUS_CAPACITY_TOGGLE, el => (el.getAttribute('checked') === "checked" ? true : false)); | ||
|
||
return { enableStatusBasedCapacityModel }; | ||
} | ||
|
||
public async apply(config: Config): Promise<void> { | ||
// Open the omni-channel setup page | ||
const page = await this.browserforce.openPage(PATHS.BASE); | ||
|
||
// Click the checkbox | ||
const capacityModel = await page.waitForSelector(SELECTORS.STATUS_CAPACITY_TOGGLE); | ||
await capacityModel.click(); | ||
|
||
// Save the settings | ||
const saveButton = await page.waitForSelector(SELECTORS.SAVE_BUTTON); | ||
await saveButton.click(); | ||
|
||
// Wait for the page to refresh | ||
await page.waitForNavigation() | ||
|
||
// Close the page | ||
await page.close(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema", | ||
"$id": "https://github.com/amtrack/sfdx-browserforce-plugin/src/plugins/omni-channel-settings/schema.json", | ||
"title": "Omni-Channel Settings", | ||
"type": "object", | ||
"properties": { | ||
"enableStatusBasedCapacityModel": { | ||
"title": "Enable Status-Based Capacity Model", | ||
"description": "Route and track work based on changes to work status and ownership.", | ||
"type": "boolean" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import assert from 'assert'; | ||
import * as child from 'child_process'; | ||
import { fileURLToPath } from 'node:url'; | ||
import * as path from 'path'; | ||
import { PermissionSets } from './index.js'; | ||
|
||
const __dirname = fileURLToPath(new URL('.', import.meta.url)); | ||
|
||
describe(PermissionSets.name, function () { | ||
this.timeout('10m'); | ||
let plugin: PermissionSets; | ||
before(() => { | ||
plugin = new PermissionSets(global.bf); | ||
}); | ||
|
||
const configurePermissionSet = [ | ||
{ | ||
permissionSetName: "ServicePresenceTest", | ||
servicePresenceStatuses: ["TestStatus", "TestStatus3"] | ||
} | ||
]; | ||
|
||
it('should create permission set and service presence status as a prerequisite', () => { | ||
const sourceDeployCmd = child.spawnSync('sf', [ | ||
'project', | ||
'deploy', | ||
'start', | ||
'-d', | ||
path.join(__dirname, 'sfdx-source'), | ||
'--json' | ||
]); | ||
assert.deepStrictEqual(sourceDeployCmd.status, 0, sourceDeployCmd.output.toString()); | ||
}); | ||
|
||
it('should configure permission set presence status', async () => { | ||
await plugin.run(configurePermissionSet); | ||
const res = await plugin.retrieve(configurePermissionSet); | ||
assert.deepStrictEqual(res, configurePermissionSet); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { BrowserforcePlugin } from '../../plugin.js'; | ||
import { ServicePresenceStatus } from './service-presence-status/index.js'; | ||
|
||
type PermissionSet = { | ||
permissionSetName: string; | ||
servicePresenceStatuses: string[]; | ||
}; | ||
|
||
export class PermissionSets extends BrowserforcePlugin { | ||
public async retrieve(definition?: PermissionSet[]): Promise<PermissionSet[]> { | ||
const pluginServicePresenceStatus = new ServicePresenceStatus(this.browserforce); | ||
|
||
const permissionSets: PermissionSet[] = []; | ||
|
||
for await (const permissionSet of definition) { | ||
permissionSets.push({ | ||
permissionSetName: permissionSet.permissionSetName, | ||
servicePresenceStatuses: await pluginServicePresenceStatus.retrieve(permissionSet) | ||
}); | ||
} | ||
|
||
return permissionSets; | ||
} | ||
|
||
public async apply(plan: PermissionSet[]): Promise<void> { | ||
const pluginServicePresenceStatus = new ServicePresenceStatus(this.browserforce); | ||
|
||
for await (const permissionSet of plan) { | ||
await pluginServicePresenceStatus.apply(permissionSet); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema", | ||
"$id": "https://github.com/amtrack/sfdx-browserforce-plugin/src/plugins/permission-sets/schema.json", | ||
"title": "Permission Sets", | ||
"type": "array", | ||
"items": { "$ref": "#/definitions/permissionSet" }, | ||
"default": [], | ||
"definitions": { | ||
"permissionSet": { | ||
"type": "object", | ||
"properties": { | ||
"permissionSetName": { | ||
"title": "Permission Set", | ||
"description": "The name of the Permission Set to modify", | ||
"type": "string" | ||
}, | ||
"servicePresenceStatuses": { | ||
"$ref": "./service-presence-status/schema.json" | ||
} | ||
}, | ||
"required": ["permissionSetName"] | ||
} | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
src/plugins/permission-sets/service-presence-status/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { BrowserforcePlugin } from '../../../plugin.js'; | ||
|
||
const SELECTORS = { | ||
ADD_BUTTON: 'a[id$=":duelingListBox:backingList_add"]', | ||
REMOVE_BUTTON: 'a[id$=":duelingListBox:backingList_remove"]', | ||
SAVE_BUTTON: 'input[id$=":button_pc_save"]', | ||
VALUES_AVAILABLE: 'select[id$=":duelingListBox:backingList_a"]:not([disabled="disabled"])', | ||
VALUES_ENABLED: 'select[id$=":duelingListBox:backingList_s"]:not([disabled="disabled"])' | ||
}; | ||
|
||
type PermissionSet = { | ||
permissionSetName: string; | ||
servicePresenceStatuses: string[]; | ||
}; | ||
|
||
export class ServicePresenceStatus extends BrowserforcePlugin { | ||
public async retrieve(definition: PermissionSet): Promise<string[]> { | ||
// Query for the permission set | ||
const permissionSetName = definition.permissionSetName; | ||
const permissionSet = await this.org.getConnection().singleRecordQuery( | ||
`SELECT Id FROM PermissionSet WHERE Name='${permissionSetName}'` | ||
); | ||
|
||
// Open the permission set setup page | ||
const page = await this.browserforce.openPage(`${permissionSet.Id}/e?s=ServicePresenceStatusAccess`); | ||
|
||
const enabledServicePresenceStatuses = await page.$$eval(`${SELECTORS.VALUES_ENABLED} > option`, (options) => { | ||
return options.map((option) => option.title ?? ''); | ||
}); | ||
|
||
return enabledServicePresenceStatuses; | ||
} | ||
|
||
public async apply(config: PermissionSet): Promise<void> { | ||
// Query for the permission set | ||
const permissionSetName = config.permissionSetName; | ||
const permissionSet = await this.org.getConnection().singleRecordQuery( | ||
`SELECT Id FROM PermissionSet WHERE Name='${permissionSetName}'` | ||
); | ||
|
||
// Open the permission set setup page | ||
const page = await this.browserforce.openPage(`${permissionSet.Id}/e?s=ServicePresenceStatusAccess`); | ||
|
||
if (config?.servicePresenceStatuses) { | ||
await page.waitForSelector(`${SELECTORS.VALUES_AVAILABLE} > option`); | ||
|
||
const availableElements = await page.$$(`${SELECTORS.VALUES_AVAILABLE} > option`); | ||
|
||
for (const availableElement of availableElements) { | ||
const optionTitle = (await availableElement.evaluate(node => node.getAttribute('title')))?.toString(); | ||
|
||
if (optionTitle && config.servicePresenceStatuses.includes(optionTitle)) { | ||
await availableElement.click(); | ||
await page.click(SELECTORS.ADD_BUTTON); | ||
} | ||
} | ||
|
||
await page.waitForSelector(`${SELECTORS.VALUES_ENABLED} > option`); | ||
const enabledElements = await page.$$(`${SELECTORS.VALUES_ENABLED} > option`); | ||
|
||
for (const enabledElement of enabledElements) { | ||
const optionTitle = (await enabledElement.evaluate(node => node.getAttribute('title')))?.toString(); | ||
|
||
if (optionTitle && !config.servicePresenceStatuses.includes(optionTitle)) { | ||
await enabledElement.click(); | ||
await page.click(SELECTORS.REMOVE_BUTTON); | ||
} | ||
} | ||
} | ||
|
||
// Save the settings and wait for page refresh | ||
await Promise.all([ | ||
page.waitForNavigation(), | ||
page.click(SELECTORS.SAVE_BUTTON) | ||
]); | ||
|
||
// Close the page | ||
await page.close(); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
src/plugins/permission-sets/service-presence-status/schema.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema", | ||
"$id": "https://github.com/amtrack/sfdx-browserforce-plugin/src/plugins/permission-sets/schema.json", | ||
"title": "Service Presence Statuses", | ||
"type": "array", | ||
"default": [] | ||
} |
5 changes: 5 additions & 0 deletions
5
...ins/permission-sets/sfdx-source/permissionsets/ServicePresenceTest.permissionset-meta.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<hasActivationRequired>false</hasActivationRequired> | ||
<label>ServicePresenceTest</label> | ||
</PermissionSet> |
4 changes: 4 additions & 0 deletions
4
...ission-sets/sfdx-source/servicePresenceStatuses/TestStatus.servicePresenceStatus-meta.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ServicePresenceStatus xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<label>TestStatus</label> | ||
</ServicePresenceStatus> |
4 changes: 4 additions & 0 deletions
4
...ssion-sets/sfdx-source/servicePresenceStatuses/TestStatus2.servicePresenceStatus-meta.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ServicePresenceStatus xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<label>TestStatus2</label> | ||
</ServicePresenceStatus> |
4 changes: 4 additions & 0 deletions
4
...ssion-sets/sfdx-source/servicePresenceStatuses/TestStatus3.servicePresenceStatus-meta.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ServicePresenceStatus xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<label>TestStatus3</label> | ||
</ServicePresenceStatus> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.