diff --git a/frontend/app/components/Alerts/Notifications/Notifications.js b/frontend/app/components/Alerts/Notifications/Notifications.js index 7332b8a85..72aa8db8d 100644 --- a/frontend/app/components/Alerts/Notifications/Notifications.js +++ b/frontend/app/components/Alerts/Notifications/Notifications.js @@ -108,8 +108,8 @@ class Notifications extends React.Component { content={
{ inCall ? 'End Call' : 'Call' }
} - content={ `Call ${userId ? userId : 'User'}` } + content={ cannotCall ? "You don’t have the permissions to perform this action." : `Call ${userId ? userId : 'User'}` } size="tiny" inverted position="top right" diff --git a/frontend/app/components/BugFinder/EventFilter/EventFilter.js b/frontend/app/components/BugFinder/EventFilter/EventFilter.js index 1502b5caf..44fe0bf00 100644 --- a/frontend/app/components/BugFinder/EventFilter/EventFilter.js +++ b/frontend/app/components/BugFinder/EventFilter/EventFilter.js @@ -130,7 +130,8 @@ export default class EventFilter extends React.PureComponent { onClick={ this.onPlaceholderClick } > { !searchQuery && - +
Search for users, clicks, page visits, requests, errors and more
+ // } } diff --git a/frontend/app/components/BugFinder/EventFilter/eventFilter.css b/frontend/app/components/BugFinder/EventFilter/eventFilter.css index 22b7485cd..976fd4640 100644 --- a/frontend/app/components/BugFinder/EventFilter/eventFilter.css +++ b/frontend/app/components/BugFinder/EventFilter/eventFilter.css @@ -56,4 +56,22 @@ position: absolute; right: 9px; top: 9px; +} + +.placeholder { + color: $gray-medium; + font-weight: 300; + font-size: 16px; + user-select: none; + + & span { + font-weight: 400; + color: $teal; + cursor: pointer; + border-bottom: dashed thin $teal; + + &:hover { + color: $teal-dark; + } + } } \ No newline at end of file diff --git a/frontend/app/components/Client/CustomFields/CustomFields.js b/frontend/app/components/Client/CustomFields/CustomFields.js index 50b551242..2b875e439 100644 --- a/frontend/app/components/Client/CustomFields/CustomFields.js +++ b/frontend/app/components/Client/CustomFields/CustomFields.js @@ -100,6 +100,7 @@ class CustomFields extends React.Component { title="No data available." size="small" show={ fields.size === 0 } + icon >
{ fields.filter(i => i.index).map(field => ( diff --git a/frontend/app/components/Client/Integrations/AssistDoc/AssistScript.tsx b/frontend/app/components/Client/Integrations/AssistDoc/AssistScript.tsx index 3215df3d2..107a33351 100644 --- a/frontend/app/components/Client/Integrations/AssistDoc/AssistScript.tsx +++ b/frontend/app/components/Client/Integrations/AssistDoc/AssistScript.tsx @@ -23,7 +23,7 @@ function AssistScript(props) { r.issue=function(k,p){r.push([6,k,p])}; r.isActive=function(){return false}; r.getSessionToken=function(){}; -})(0, "${props.projectKey}", "//static.openreplay.com/3.4.0/openreplay-assist.js",1,28); +})(0, "${props.projectKey}", "//static.openreplay.com/3.4.9/openreplay-assist.js",1,28); `}
diff --git a/frontend/app/components/Client/ManageUsers/ManageUsers.js b/frontend/app/components/Client/ManageUsers/ManageUsers.js index e70157cd0..c9df52d17 100644 --- a/frontend/app/components/Client/ManageUsers/ManageUsers.js +++ b/frontend/app/components/Client/ManageUsers/ManageUsers.js @@ -50,7 +50,7 @@ class ManageUsers extends React.PureComponent { } adminLabel = (user) => { - if (user.superAdmin) return 'Owner'; + if (user.superAdmin) return null; return user.admin ? 'Admin' : ''; }; @@ -207,8 +207,8 @@ class ManageUsers extends React.PureComponent {
- { !hideHeader &&

{ (isAdmin ? 'Manage ' : '') + 'Users' }

} - { hideHeader &&

{ `Team Size ${members.size}` }

} + { !hideHeader &&

{ (isAdmin ? 'Manage ' : '') + `Users (${members.size})` }

} + { hideHeader &&

{ `Users (${members.size})` }

} diff --git a/frontend/app/components/Client/ManageUsers/UserItem.js b/frontend/app/components/Client/ManageUsers/UserItem.js index b40b5182a..757f709a9 100644 --- a/frontend/app/components/Client/ManageUsers/UserItem.js +++ b/frontend/app/components/Client/ManageUsers/UserItem.js @@ -6,6 +6,7 @@ const UserItem = ({ user, adminLabel, deleteHandler, editHandler, generateInvite
{ user.name || user.email }
+
{ adminLabel &&
{ adminLabel }
} { user.roleName &&
{ user.roleName }
}
diff --git a/frontend/app/components/Client/ManageUsers/userItem.css b/frontend/app/components/Client/ManageUsers/userItem.css index 6de747561..e11592408 100644 --- a/frontend/app/components/Client/ManageUsers/userItem.css +++ b/frontend/app/components/Client/ManageUsers/userItem.css @@ -16,11 +16,11 @@ } & .adminLabel { - margin-left: 10px; + margin-left: 5px; padding: 0 10px; border-radius: 3px; background-color: $gray-lightest; - font-size: 12px; + font-size: 10px; border: solid thin $gray-light; } } diff --git a/frontend/app/components/Client/ProfileSettings/Licenses.js b/frontend/app/components/Client/ProfileSettings/Licenses.js index 4e487120c..748d5bb80 100644 --- a/frontend/app/components/Client/ProfileSettings/Licenses.js +++ b/frontend/app/components/Client/ProfileSettings/Licenses.js @@ -6,8 +6,8 @@ function Licenses({ account }) {
{account.license}
{account.expirationDate && ( -
- Expires At: {account.expirationDate.toFormat('LLL dd, yyyy')} +
+ (Expires on {account.expirationDate.toFormat('LLL dd, yyyy')})
)}
diff --git a/frontend/app/components/Client/ProfileSettings/ProfileSettings.js b/frontend/app/components/Client/ProfileSettings/ProfileSettings.js index 5df0d1aec..b12b2cf8c 100644 --- a/frontend/app/components/Client/ProfileSettings/ProfileSettings.js +++ b/frontend/app/components/Client/ProfileSettings/ProfileSettings.js @@ -76,6 +76,7 @@ export default class ProfileSettings extends React.PureComponent {

{ 'License' }

+
{ 'License key and expiration date.' }
diff --git a/frontend/app/components/Client/Roles/Roles.tsx b/frontend/app/components/Client/Roles/Roles.tsx index 65bbcfdfb..91ab2fda5 100644 --- a/frontend/app/components/Client/Roles/Roles.tsx +++ b/frontend/app/components/Client/Roles/Roles.tsx @@ -7,6 +7,7 @@ import RoleForm from './components/RoleForm' import { init, edit, fetchList, remove as deleteRole } from 'Duck/roles'; import RoleItem from './components/RoleItem' import { confirm } from 'UI/Confirmation'; +import { toast } from 'react-toastify'; interface Props { loading: boolean @@ -14,20 +15,18 @@ interface Props { edit: (role: any) => void, instance: any, roles: any[], - deleteRole: (id: any) => void, + deleteRole: (id: any) => Promise, fetchList: () => Promise, account: any, - permissionsMap: any + permissionsMap: any, + removeErrors: any } function Roles(props: Props) { - const { loading, instance, roles, init, edit, deleteRole, account, permissionsMap } = props + const { loading, instance, roles, init, edit, deleteRole, account, permissionsMap, removeErrors } = props const [showModal, setShowmModal] = useState(false) const isAdmin = account.admin || account.superAdmin; - console.log('permissionsMap', permissionsMap) - - useEffect(() => { props.fetchList() }, []) @@ -49,7 +48,13 @@ function Roles(props: Props) { header: 'Roles', confirmation: `Are you sure you want to remove this role?` })) { - deleteRole(role.roleId) + deleteRole(role.roleId).then(() => { + if (removeErrors && removeErrors.size > 0) { + removeErrors.forEach(e => { + toast.error(e) + }) + } + }) } } @@ -80,6 +85,7 @@ function Roles(props: Props) { />
} + content="You don’t have the permissions to perform this action." disabled={ isAdmin } size="tiny" inverted @@ -98,6 +104,7 @@ function Roles(props: Props) { {roles.map(role => ( { instance: state.getIn(['roles', 'instance']) || null, permissionsMap: permissionsMap, roles: state.getIn(['roles', 'list']), + removeErrors: state.getIn(['roles', 'removeRequest', 'errors']), loading: state.getIn(['roles', 'fetchRequest', 'loading']), account: state.getIn([ 'user', 'account' ]) } diff --git a/frontend/app/components/Client/Roles/components/RoleItem/RoleItem.tsx b/frontend/app/components/Client/Roles/components/RoleItem/RoleItem.tsx index c4cdb7a25..2ef271a46 100644 --- a/frontend/app/components/Client/Roles/components/RoleItem/RoleItem.tsx +++ b/frontend/app/components/Client/Roles/components/RoleItem/RoleItem.tsx @@ -13,34 +13,37 @@ interface Props { role: any, deleteHandler?: (role: any) => void, editHandler?: (role: any) => void, - permissions: any + permissions: any, + isAdmin: boolean } -function RoleItem({ role, deleteHandler, editHandler, permissions }: Props) { +function RoleItem({ role, deleteHandler, editHandler, isAdmin, permissions }: Props) { return (
- { role.name } -
+
{ role.name }
+
{role.permissions.map((permission: any) => ( // { permissions[permission].name } ))}
+ { isAdmin && ( +
+ { !!deleteHandler && +
deleteHandler(role) } id="trash"> + +
+ } + { !!editHandler && +
editHandler(role) }> + +
+ } +
+ )} -
- { !!deleteHandler && -
deleteHandler(role) } id="trash"> - -
- } - { !!editHandler && -
editHandler(role) }> - -
- } -
); } diff --git a/frontend/app/components/Client/Roles/components/RoleItem/roleItem.css b/frontend/app/components/Client/Roles/components/RoleItem/roleItem.css index 7173d1c33..af0aab35d 100644 --- a/frontend/app/components/Client/Roles/components/RoleItem/roleItem.css +++ b/frontend/app/components/Client/Roles/components/RoleItem/roleItem.css @@ -38,10 +38,10 @@ .label { margin-left: 10px; - padding: 0 10px; + padding: 0 5px; border-radius: 3px; background-color: $gray-lightest; - font-size: 12px; + font-size: 10px; border: solid thin $gray-light; width: fit-content; } \ No newline at end of file diff --git a/frontend/app/components/Client/Webhooks/Webhooks.js b/frontend/app/components/Client/Webhooks/Webhooks.js index 61d30345e..100887285 100644 --- a/frontend/app/components/Client/Webhooks/Webhooks.js +++ b/frontend/app/components/Client/Webhooks/Webhooks.js @@ -56,7 +56,7 @@ class Webhooks extends React.PureComponent { - { icon && } + {/* { icon && } */} { name } { message }
diff --git a/frontend/app/components/Session/Session.js b/frontend/app/components/Session/Session.js index 36fa66d7f..af1cdb3d3 100644 --- a/frontend/app/components/Session/Session.js +++ b/frontend/app/components/Session/Session.js @@ -5,6 +5,7 @@ import { fetch as fetchSession } from 'Duck/sessions'; import { fetchList as fetchSlackList } from 'Duck/integrations/slack'; import { Link, NoContent, Loader } from 'UI'; import { sessions as sessionsRoute } from 'App/routes'; +import withPermissions from 'HOCs/withPermissions' import LivePlayer from './LivePlayer'; import WebPlayer from './WebPlayer'; @@ -56,7 +57,7 @@ function Session({ ); } -export default connect((state, props) => { +export default withPermissions(['SESSION_REPLAY'])(connect((state, props) => { const { match: { params: { sessionId } } } = props; return { sessionId, @@ -67,4 +68,4 @@ export default connect((state, props) => { }, { fetchSession, fetchSlackList, -})(Session); \ No newline at end of file +})(Session)); \ No newline at end of file diff --git a/frontend/app/components/Session_/Autoplay/Autoplay.js b/frontend/app/components/Session_/Autoplay/Autoplay.js index ef501f3e6..6b5279cfe 100644 --- a/frontend/app/components/Session_/Autoplay/Autoplay.js +++ b/frontend/app/components/Session_/Autoplay/Autoplay.js @@ -24,7 +24,7 @@ function Autoplay(props) { name="sessionsLive" onChange={ props.toggleAutoplay } checked={ autoplay } - style={{ margin: '0 10px' }} + style={{ margin: '0px 10px 0px 12px'}} /> } tooltip={'Autoplay'} diff --git a/frontend/app/components/Session_/EventsBlock/Metadata/Metadata.js b/frontend/app/components/Session_/EventsBlock/Metadata/Metadata.js index 03171cdd0..9b5d9ce66 100644 --- a/frontend/app/components/Session_/EventsBlock/Metadata/Metadata.js +++ b/frontend/app/components/Session_/EventsBlock/Metadata/Metadata.js @@ -38,7 +38,7 @@ export default connect(state => ({ /> { visible &&
- + { metadata.map((i) => { const key = Object.keys(i)[0] const value = i[key] diff --git a/frontend/app/components/Session_/Fetch/Fetch.js b/frontend/app/components/Session_/Fetch/Fetch.js index f316921f5..71e7a2fb9 100644 --- a/frontend/app/components/Session_/Fetch/Fetch.js +++ b/frontend/app/components/Session_/Fetch/Fetch.js @@ -49,7 +49,7 @@ export default class Fetch extends React.PureComponent { const { filter, current, currentIndex } = this.state; const filterRE = getRE(filter, 'i'); const filtered = list - .filter(({ name }) => filterRE.test(name)); + .filter((r) => filterRE.test(r.name) || filterRE.test(r.url) || filterRE.test(r.method) || filterRE.test(r.status)); return ( @@ -90,7 +90,7 @@ export default class Fetch extends React.PureComponent {

Fetch

{ const { history, siteId, funnelPage } = this.props; - if (funnelPage) { - if (funnelPage.get('issueId')) { - history.push(withSiteId(funnelIssueRoute(funnelPage.get('funnelId'), funnelPage.get('issueId')), siteId)) + const funnelId = funnelPage && funnelPage.get('funnelId'); + const issueId = funnelPage && funnelPage.get('issueId'); + if (funnelId || issueId) { + if (issueId) { + history.push(withSiteId(funnelIssueRoute(funnelId, issueId), siteId)) } else - history.push(withSiteId(funnelRoute(funnelPage.get('funnelId')), siteId)); + history.push(withSiteId(funnelRoute(funnelId), siteId)); } else history.push(withSiteId(SESSIONS_ROUTE), siteId); } diff --git a/frontend/app/duck/roles.js b/frontend/app/duck/roles.js index f1dd1ecec..67c9a79df 100644 --- a/frontend/app/duck/roles.js +++ b/frontend/app/duck/roles.js @@ -13,8 +13,8 @@ const initialState = Map({ { name: 'Developer Tools', value: 'DEV_TOOLS' }, { name: 'Errors', value: 'ERRORS' }, { name: 'Metrics', value: 'METRICS' }, - { name: 'Assist Live', value: 'ASSIST_LIVE' }, - { name: 'Assist Call', value: 'ASSIST_CALL' }, + { name: 'Assist (Live)', value: 'ASSIST_LIVE' }, + { name: 'Assist (Call)', value: 'ASSIST_CALL' }, ]) }); diff --git a/frontend/app/styles/semantic.css b/frontend/app/styles/semantic.css index 69a8828b9..cf6034861 100644 --- a/frontend/app/styles/semantic.css +++ b/frontend/app/styles/semantic.css @@ -309,4 +309,8 @@ a:hover { color: $teal; +} + +.ui.toggle.checkbox { + min-height: 20px !important; } \ No newline at end of file diff --git a/scripts/helm/vars.yaml b/scripts/helm/vars.yaml index 5941894be..f106f03af 100644 --- a/scripts/helm/vars.yaml +++ b/scripts/helm/vars.yaml @@ -93,7 +93,7 @@ aws_region: "us-east-1" assets_bucket: sessions-assets recordings_bucket: mobs sourcemaps_bucket: sourcemaps -kafka_endpoint: kafka.db.svc.cluster.local:9042 +kafka_endpoint: kafka.db.svc.cluster.local:9092 kafka_ssl: 'false' postgres_endpoint: postgresql.db.svc.cluster.local postgres_port: 5432