Merge pull request #121 from openreplay/dev

fix(ui) - review changes and other fixes
This commit is contained in:
Shekar Siri 2021-08-05 18:29:34 +05:30 committed by GitHub
commit c65a7b9561
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 46 additions and 57 deletions

View file

@ -502,15 +502,12 @@ def edit_gdpr(projectId, context):
return {"data": projects.edit_gdpr(project_id=projectId, gdpr=data)}
@app.route('/password/reset/{step}', methods=['PUT', 'POST'], authorizer=None)
def reset_password_handler(step):
@app.route('/password/reset-link', methods=['PUT', 'POST'], authorizer=None)
def reset_password_handler():
data = app.current_request.json_body
if step == "1":
if "email" not in data or len(data["email"]) < 5:
return {"errors": ["please provide a valid email address"]}
return reset_password.step1(data)
# elif step == "2":
# return reset_password.step2(data)
if "email" not in data or len(data["email"]) < 5:
return {"errors": ["please provide a valid email address"]}
return reset_password.reset(data)
@app.route('/{projectId}/metadata', methods=['GET'])

View file

@ -375,7 +375,7 @@ def process_invitation_link():
'Content-Type': 'text/plain'})
@app.route('/users/invitation/password', methods=['POST', 'PUT'], authorizer=None)
@app.route('/password/reset', methods=['POST', 'PUT'], authorizer=None)
def change_password_by_invitation():
data = app.current_request.json_body
if data is None or len(data.get("invitation", "")) < 64 or len(data.get("pass", "")) < 8:

View file

@ -1,13 +1,9 @@
import chalicelib.utils.TimeUTC
from chalicelib.utils import email_helper, captcha, helper
import secrets
from chalicelib.utils import pg_client
from chalicelib.core import users
def step1(data):
print("====================== reset password 1 ===============")
def reset(data):
print("====================== reset password ===============")
print(data)
if helper.allow_captcha() and not captcha.is_valid(data["g-recaptcha-response"]):
print("error: Invalid captcha.")
@ -21,20 +17,9 @@ def step1(data):
return {"errors": ["multiple users, please contact our support"]}
elif len(a_users) == 1:
a_users = a_users[0]
invitation_link=users.generate_new_invitation(user_id=a_users["id"])
invitation_link = users.generate_new_invitation(user_id=a_users["id"])
email_helper.send_forgot_password(recipient=data["email"], invitation_link=invitation_link)
else:
print(f"invalid email address [{data['email']}]")
return {"errors": ["invalid email address"]}
return {"data": {"state": "success"}}
# def step2(data):
# print("====================== change password 2 ===============")
# user = users.get_by_email_reset(data["email"], data["code"])
# if not user:
# print("error: wrong email or reset code")
# return {"errors": ["wrong email or reset code"]}
# users.update(tenant_id=user["tenantId"], user_id=user["id"],
# changes={"token": None, "password": data["password"], "generatedPassword": False})
# return {"data": {"state": "success"}}

View file

@ -107,7 +107,6 @@ def generate_new_invitation(user_id):
return __get_invitation_link(cur.fetchone().pop("invitation_token"))
def reset_member(tenant_id, editor_id, user_id_to_update):
admin = get(tenant_id=tenant_id, user_id=editor_id)
if not admin["admin"] and not admin["superAdmin"]:
@ -282,6 +281,8 @@ def edit(user_id_to_update, tenant_id, changes, editor_id):
admin = get(tenant_id=tenant_id, user_id=editor_id)
if not admin["superAdmin"] and not admin["admin"]:
return {"errors": ["unauthorized"]}
if user["superAdmin"]:
changes.pop("admin")
keys = list(changes.keys())
for k in keys:

View file

@ -107,7 +107,6 @@ def generate_new_invitation(user_id):
)
return __get_invitation_link(cur.fetchone().pop("invitation_token"))
def reset_member(tenant_id, editor_id, user_id_to_update):
admin = get(tenant_id=tenant_id, user_id=editor_id)
@ -287,6 +286,8 @@ def edit(user_id_to_update, tenant_id, changes, editor_id):
admin = get(tenant_id=tenant_id, user_id=editor_id)
if not admin["superAdmin"] and not admin["admin"]:
return {"errors": ["unauthorized"]}
if user["superAdmin"] and "admin" in changes:
changes.pop("admin")
keys = list(changes.keys())
for k in keys:

View file

@ -103,7 +103,7 @@ class ManageUsers extends React.PureComponent {
</div>
{ !account.smtp &&
<div className={cn("mb-4 p-2", styles.smtpMessage)}>
SMTP is not configured, <a className="link" href="https://docs.openreplay.com/configuration/configure-smtp" target="_blank">setup SMTP</a>
SMTP is not configured. Please follow <a className="link" href="https://docs.openreplay.com/configuration/configure-smtp" target="_blank">these steps</a> to set it up.
</div>
}
<div className={ styles.formGroup }>
@ -114,6 +114,7 @@ class ManageUsers extends React.PureComponent {
value={ member.admin }
checked={ !!member.admin }
onChange={ this.onChangeCheckbox }
disabled={member.superAdmin}
/>
<span>{ 'Admin' }</span>
</label>
@ -199,14 +200,7 @@ class ManageUsers extends React.PureComponent {
inverted
position="top left"
/>
</div>
<div>
{ !account.smtp &&
<BannerMessage>
Inviting new users require email messaging. Please <a className="link" href="https://docs.openreplay.com/configuration/configure-smtp" target="_blank">setup SMTP</a>.
</BannerMessage>
}
</div>
</div>
</div>
<NoContent

View file

@ -23,7 +23,7 @@ const Item = ({ icon, text, completed, active, onClick }) => (
<div className={cn('flex', stl.step)}>
<div className={
cn(
"h-6 w-6 mr-3 bg-white rounded-full flex items-center justify-center",
"h-6 w-6 mr-3 rounded-full flex items-center justify-center",
stl.iconWrapper,
{'bg-gray-light' : !active || !completed }
)}
@ -31,7 +31,7 @@ const Item = ({ icon, text, completed, active, onClick }) => (
{ completed &&
<Icon
name={icon}
color={completed? 'white' : 'gray-medium' }
color={active? 'white' : 'gray-medium' }
size="18"
/>
}

View file

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react'
import { Dropdown, Loader } from 'UI'
import React, { useEffect, useState } from 'react';
import { Dropdown, Loader } from 'UI';
import DateRange from 'Shared/DateRange';
import { connect } from 'react-redux';
import { fetchInsights } from 'Duck/sessions';
@ -15,10 +15,14 @@ interface Props {
events: Array<any>
urlOptions: Array<any>
loading: boolean
host: string
}
function PageInsightsPanel({ filters, fetchInsights, events = [], insights, urlOptions, loading = true }: Props) {
function PageInsightsPanel({
filters, fetchInsights, events = [], insights, urlOptions, host, loading = true
}: Props) {
const [insightsFilters, setInsightsFilters] = useState(filters)
console.log('host', host)
const onDateChange = (e) => {
const { startDate, endDate, rangeValue } = e;
@ -33,7 +37,7 @@ function PageInsightsPanel({ filters, fetchInsights, events = [], insights, urlO
}, [insights])
useEffect(() => {
const url = insightsFilters.url ? insightsFilters.url : urlOptions[0].value;
const url = insightsFilters.url ? insightsFilters.url : host + '/' + urlOptions[0].value;
Player.pause();
fetchInsights({ ...insightsFilters, url })
}, [insightsFilters])
@ -41,7 +45,7 @@ function PageInsightsPanel({ filters, fetchInsights, events = [], insights, urlO
const onPageSelect = (e, { name, value }) => {
const event = events.find(item => item.url === value)
Player.jump(event.time + JUMP_OFFSET)
setInsightsFilters({ ...insightsFilters, url: value })
setInsightsFilters({ ...insightsFilters, url: host + '/' + value })
markTargets([])
};
@ -83,9 +87,10 @@ export default connect(state => {
const events = state.getIn([ 'sessions', 'visitedEvents' ])
return {
filters: state.getIn(['sessions', 'insightFilters']),
host: state.getIn([ 'sessions', 'host' ]),
insights: state.getIn([ 'sessions', 'insights' ]),
events: events,
urlOptions: events.map(({ url }) => ({ text: url, value: url})),
urlOptions: events.map(({ url, host }) => ({ text: url, value: url, host })),
loading: state.getIn([ 'sessions', 'fetchInsightsRequest', 'loading' ]),
}
}, { fetchInsights })(PageInsightsPanel);

View file

@ -155,7 +155,7 @@ export default class SignupForm extends React.Component {
<div className={ stl.formFooter }>
<Button type="submit" primary >
{ loading ?
<CircularLoader loading={true} /> :
<CircularLoader loading={true} className="flex" /> :
'Create account'
}
</Button>

View file

@ -53,7 +53,8 @@ const initialState = Map({
liveSessions: List(),
visitedEvents: List(),
insights: List(),
insightFilters: defaultDateFilters
insightFilters: defaultDateFilters,
host: ''
});
const reducer = (state = initialState, action = {}) => {
@ -146,7 +147,7 @@ const reducer = (state = initialState, action = {}) => {
// TODO: more common.. or TEMP
const events = action.filter.events;
// const filters = action.filter.filters;
const current = state.get('list').find(({ sessionId }) => sessionId === action.data.sessionId) || Session();
const current = state.get('list').find(({ sessionId }) => sessionId === action.data.sessionId) || Session();
const session = Session(action.data);
const matching = [];
@ -158,7 +159,7 @@ const reducer = (state = initialState, action = {}) => {
tmpMap[event.url] = event.url
visitedEvents.push(event)
}
})
})
events.forEach(({ key, operator, value }) => {
session.events.forEach((e, index) => {
@ -172,10 +173,12 @@ const reducer = (state = initialState, action = {}) => {
}
}
})
})
})
console.log('visitedEvents', visitedEvents)
return state.set('current', current.merge(session))
.set('eventsIndex', matching)
.set('visitedEvents', visitedEvents);
.set('visitedEvents', visitedEvents)
.set('host', visitedEvents[0].host);
}
case FETCH_FAVORITE_LIST.SUCCESS:
return state
@ -227,7 +230,7 @@ const reducer = (state = initialState, action = {}) => {
.set('sessionIds', allList.map(({ sessionId }) => sessionId ).toJS())
case SET_TIMEZONE:
return state.set('timezone', action.timezone)
case TOGGLE_CHAT_WINDOW:
case TOGGLE_CHAT_WINDOW:
return state.set('showChatWindow', action.state)
case FETCH_INSIGHTS.SUCCESS: 
return state.set('insights', List(action.data).sort((a, b) => b.count - a.count));

View file

@ -113,12 +113,12 @@ export const signup = params => dispatch => dispatch({
export const resetPassword = params => dispatch => dispatch({
types: RESET_PASSWORD.toArray(),
call: client => client.post('/password/reset/2', params),
call: client => client.post('/password/reset', params)
});
export const requestResetPassword = params => dispatch => dispatch({
types: REQUEST_RESET_PASSWORD.toArray(),
call: client => client.post('/password/reset/1', params),
call: client => client.post('/password/reset-link', params),
});
export const updatePassword = params => dispatch => dispatch({

View file

@ -56,6 +56,7 @@ const View = Event.extend({
const Location = Event.extend({
type: LOCATION,
url: '',
host: '',
pageLoad: false,
fcpTime: undefined,
//fpTime: undefined,

View file

@ -13,14 +13,14 @@ const oss = {
ORIGIN: () => 'window.location.origin',
API_EDP: () => 'window.location.origin + "/api"',
ASSETS_HOST: () => 'window.location.origin + "/assets"',
VERSION: '1.2.0',
VERSION: '1.3.0',
SOURCEMAP: true,
MINIO_ENDPOINT: process.env.MINIO_ENDPOINT,
MINIO_PORT: process.env.MINIO_PORT,
MINIO_USE_SSL: process.env.MINIO_USE_SSL,
MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
TRACKER_VERSION: '3.1.0', // trackerInfo.version,
TRACKER_VERSION: '3.2.0', // trackerInfo.version,
}
module.exports = {

View file

@ -29,6 +29,7 @@ env:
AWS_SECRET_ACCESS_KEY: "m1n10s3CretK3yPassw0rd"
AWS_REGION: us-east-1
POSTGRES_STRING: postgres://postgres:asayerPostgres@postgresql.db.svc.cluster.local:5432
CACHE_ASSETS: true
#
REDIS_STRING: redis-master.db.svc.cluster.local:6379
KAFKA_SERVERS: kafka.db.svc.cluster.local:9092

View file

@ -13,6 +13,7 @@ env:
sourcemaps_bucket_key: "{{ minio_access_key }}"
sourcemaps_bucket_secret: "{{ minio_secret_key }}"
S3_HOST: "https://{{ domain_name }}"
SITE_URL: "https://{{ domain_name }}"
jwt_secret: "{{ jwt_secret_key }}"
{% if env is defined and env.chalice is defined and env.chalice%}
{{ env.chalice | to_nice_yaml | trim | indent(2) }}