mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #10933 from overleaf/ab-hackathon-split-tests-fancy-dash
[web/analytics] Split test dashboard improvements GitOrigin-RevId: 7711060111c043a3002f30381c292249a84c320e
This commit is contained in:
parent
971dabb1f8
commit
55e05d2fb6
8 changed files with 118 additions and 9 deletions
65
package-lock.json
generated
65
package-lock.json
generated
|
@ -12655,6 +12655,31 @@
|
||||||
"is-regex": "^1.0.3"
|
"is-regex": "^1.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/chart.js": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-5/8/9eBivwBZK81mKvmIwTb2Pmw4D/5h1RK9fBWZLLZ8mCJ+kfYNmV9rMrGoa5Hgy2/wVDBMLSUDudul2/9ihA==",
|
||||||
|
"engines": {
|
||||||
|
"pnpm": "^7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chartjs-adapter-moment": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chartjs-adapter-moment/-/chartjs-adapter-moment-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-Uz+nTX/GxocuqXpGylxK19YG4R3OSVf8326D+HwSTsNw1LgzyIGRo+Qujwro1wy6X+soNSnfj5t2vZ+r6EaDmA==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"chart.js": ">=3.0.0",
|
||||||
|
"moment": "^2.10.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chartjs-plugin-datalabels": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chartjs-plugin-datalabels/-/chartjs-plugin-datalabels-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-14ZU30lH7n89oq+A4bWaJPnAG8a7ZTk7dKf48YAzMvJjQtjrgg5Dpk9f+LbjCF6bpx3RAGTeL13IXpKQYyRvlw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"chart.js": ">=3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/check-error": {
|
"node_modules/check-error": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
|
||||||
|
@ -29031,6 +29056,15 @@
|
||||||
"react-dom": ">=16.3.0"
|
"react-dom": ">=16.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-chartjs-2": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-u38C9OxynlNCBp+79grgXRs7DSJ9w8FuQ5/HO5FbYBbri8HSZW+9SWgjVshLkbXBfXnMGWakbHEtvN0nL2UG7Q==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"chart.js": "^4.0.0",
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-dnd": {
|
"node_modules/react-dnd": {
|
||||||
"version": "11.1.3",
|
"version": "11.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-11.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-11.1.3.tgz",
|
||||||
|
@ -38973,6 +39007,9 @@
|
||||||
"bunyan": "^1.8.15",
|
"bunyan": "^1.8.15",
|
||||||
"cache-flow": "^1.7.4",
|
"cache-flow": "^1.7.4",
|
||||||
"celebrate": "^10.0.1",
|
"celebrate": "^10.0.1",
|
||||||
|
"chart.js": "^4.0.1",
|
||||||
|
"chartjs-adapter-moment": "^1.0.1",
|
||||||
|
"chartjs-plugin-datalabels": "^2.2.0",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"codemirror": "~5.33.0",
|
"codemirror": "~5.33.0",
|
||||||
"connect-redis": "^3.1.0",
|
"connect-redis": "^3.1.0",
|
||||||
|
@ -39048,6 +39085,7 @@
|
||||||
"qrcode": "^1.4.4",
|
"qrcode": "^1.4.4",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-bootstrap": "^0.33.1",
|
"react-bootstrap": "^0.33.1",
|
||||||
|
"react-chartjs-2": "^5.0.1",
|
||||||
"react-dnd": "^11.1.3",
|
"react-dnd": "^11.1.3",
|
||||||
"react-dnd-html5-backend": "^11.1.3",
|
"react-dnd-html5-backend": "^11.1.3",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
|
@ -49552,6 +49590,9 @@
|
||||||
"chai": "^4.3.6",
|
"chai": "^4.3.6",
|
||||||
"chai-as-promised": "^7.1.1",
|
"chai-as-promised": "^7.1.1",
|
||||||
"chai-exclude": "^2.0.3",
|
"chai-exclude": "^2.0.3",
|
||||||
|
"chart.js": "^4.0.1",
|
||||||
|
"chartjs-adapter-moment": "^1.0.1",
|
||||||
|
"chartjs-plugin-datalabels": "^2.2.0",
|
||||||
"cheerio": "^1.0.0-rc.3",
|
"cheerio": "^1.0.0-rc.3",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"codemirror": "~5.33.0",
|
"codemirror": "~5.33.0",
|
||||||
|
@ -49664,6 +49705,7 @@
|
||||||
"qrcode": "^1.4.4",
|
"qrcode": "^1.4.4",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-bootstrap": "^0.33.1",
|
"react-bootstrap": "^0.33.1",
|
||||||
|
"react-chartjs-2": "^5.0.1",
|
||||||
"react-dnd": "^11.1.3",
|
"react-dnd": "^11.1.3",
|
||||||
"react-dnd-html5-backend": "^11.1.3",
|
"react-dnd-html5-backend": "^11.1.3",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
|
@ -55239,6 +55281,23 @@
|
||||||
"is-regex": "^1.0.3"
|
"is-regex": "^1.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"chart.js": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-5/8/9eBivwBZK81mKvmIwTb2Pmw4D/5h1RK9fBWZLLZ8mCJ+kfYNmV9rMrGoa5Hgy2/wVDBMLSUDudul2/9ihA=="
|
||||||
|
},
|
||||||
|
"chartjs-adapter-moment": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chartjs-adapter-moment/-/chartjs-adapter-moment-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-Uz+nTX/GxocuqXpGylxK19YG4R3OSVf8326D+HwSTsNw1LgzyIGRo+Qujwro1wy6X+soNSnfj5t2vZ+r6EaDmA==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
|
"chartjs-plugin-datalabels": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chartjs-plugin-datalabels/-/chartjs-plugin-datalabels-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-14ZU30lH7n89oq+A4bWaJPnAG8a7ZTk7dKf48YAzMvJjQtjrgg5Dpk9f+LbjCF6bpx3RAGTeL13IXpKQYyRvlw==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"check-error": {
|
"check-error": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
|
||||||
|
@ -68640,6 +68699,12 @@
|
||||||
"warning": "^3.0.0"
|
"warning": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-chartjs-2": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-u38C9OxynlNCBp+79grgXRs7DSJ9w8FuQ5/HO5FbYBbri8HSZW+9SWgjVshLkbXBfXnMGWakbHEtvN0nL2UG7Q==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"react-dnd": {
|
"react-dnd": {
|
||||||
"version": "11.1.3",
|
"version": "11.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-11.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-11.1.3.tgz",
|
||||||
|
|
|
@ -7,7 +7,7 @@ const ALPHA_PHASE = 'alpha'
|
||||||
const BETA_PHASE = 'beta'
|
const BETA_PHASE = 'beta'
|
||||||
const RELEASE_PHASE = 'release'
|
const RELEASE_PHASE = 'release'
|
||||||
|
|
||||||
async function getSplitTests({ name, activeOnly, archivedOnly }) {
|
async function getSplitTests({ name, phase, type, activeOnly, archivedOnly }) {
|
||||||
const filters = {}
|
const filters = {}
|
||||||
if (name && name !== '') {
|
if (name && name !== '') {
|
||||||
filters.name = { $regex: _.escapeRegExp(name) }
|
filters.name = { $regex: _.escapeRegExp(name) }
|
||||||
|
@ -15,6 +15,32 @@ async function getSplitTests({ name, activeOnly, archivedOnly }) {
|
||||||
if (activeOnly) {
|
if (activeOnly) {
|
||||||
filters.$where = 'this.versions[this.versions.length - 1].active === true'
|
filters.$where = 'this.versions[this.versions.length - 1].active === true'
|
||||||
}
|
}
|
||||||
|
if (type === 'split-test') {
|
||||||
|
const query =
|
||||||
|
'this.versions[this.versions.length - 1].analyticsEnabled === true'
|
||||||
|
if (filters.$where) {
|
||||||
|
filters.$where += `&& ${query}`
|
||||||
|
} else {
|
||||||
|
filters.$where = query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type === 'gradual-rollout') {
|
||||||
|
const query =
|
||||||
|
'this.versions[this.versions.length - 1].analyticsEnabled === false'
|
||||||
|
if (filters.$where) {
|
||||||
|
filters.$where += `&& ${query}`
|
||||||
|
} else {
|
||||||
|
filters.$where = query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (['alpha', 'beta', 'release'].includes(phase)) {
|
||||||
|
const query = `this.versions[this.versions.length - 1].phase === "${phase}"`
|
||||||
|
if (filters.$where) {
|
||||||
|
filters.$where += `&& ${query}`
|
||||||
|
} else {
|
||||||
|
filters.$where = query
|
||||||
|
}
|
||||||
|
}
|
||||||
if (archivedOnly) {
|
if (archivedOnly) {
|
||||||
filters.archived = true
|
filters.archived = true
|
||||||
} else {
|
} else {
|
||||||
|
@ -205,6 +231,7 @@ async function revertToPreviousVersion(name, versionNumber) {
|
||||||
}
|
}
|
||||||
const previousVersionCopy = previousVersion.toObject()
|
const previousVersionCopy = previousVersion.toObject()
|
||||||
previousVersionCopy.versionNumber = lastVersion.versionNumber + 1
|
previousVersionCopy.versionNumber = lastVersion.versionNumber + 1
|
||||||
|
previousVersionCopy.createdAt = new Date()
|
||||||
splitTest.versions.push(previousVersionCopy)
|
splitTest.versions.push(previousVersionCopy)
|
||||||
return _saveSplitTest(splitTest)
|
return _saveSplitTest(splitTest)
|
||||||
}
|
}
|
||||||
|
@ -218,11 +245,7 @@ async function archive(name) {
|
||||||
throw new OError(`Split test with ID '${name}' is already archived`)
|
throw new OError(`Split test with ID '${name}' is already archived`)
|
||||||
}
|
}
|
||||||
splitTest.archived = true
|
splitTest.archived = true
|
||||||
const previousVersionCopy =
|
splitTest.archivedAt = new Date()
|
||||||
SplitTestUtils.getCurrentVersion(splitTest).toObject()
|
|
||||||
previousVersionCopy.versionNumber += 1
|
|
||||||
previousVersionCopy.active = false
|
|
||||||
splitTest.versions.push(previousVersionCopy)
|
|
||||||
return _saveSplitTest(splitTest)
|
return _saveSplitTest(splitTest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,10 @@ const SplitTestSchema = new Schema({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
archivedAt: {
|
||||||
|
type: Date,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
badgeInfo: {
|
badgeInfo: {
|
||||||
type: BadgeInfoSchema,
|
type: BadgeInfoSchema,
|
||||||
required: false,
|
required: false,
|
||||||
|
|
|
@ -58,7 +58,7 @@ nav.navbar.navbar-default.navbar-main
|
||||||
a(href=settings.adminUrl) Switch to Admin
|
a(href=settings.adminUrl) Switch to Admin
|
||||||
if canDisplaySplitTestMenu
|
if canDisplaySplitTestMenu
|
||||||
li
|
li
|
||||||
a(href="/admin/split-test") Manage Split Tests
|
a(href="/admin/split-test") Manage Feature Flags
|
||||||
if canDisplaySurveyMenu
|
if canDisplaySurveyMenu
|
||||||
li
|
li
|
||||||
a(href="/admin/survey") Manage Surveys
|
a(href="/admin/survey") Manage Surveys
|
||||||
|
|
|
@ -40,7 +40,7 @@ nav.navbar.navbar-default.navbar-main
|
||||||
a(href=settings.adminUrl) Switch to Admin
|
a(href=settings.adminUrl) Switch to Admin
|
||||||
if canDisplaySplitTestMenu
|
if canDisplaySplitTestMenu
|
||||||
li
|
li
|
||||||
a(href="/admin/split-test") Manage Split Tests
|
a(href="/admin/split-test") Manage Feature Flags
|
||||||
if canDisplaySurveyMenu
|
if canDisplaySurveyMenu
|
||||||
li
|
li
|
||||||
a(href="/admin/survey") Manage Surveys
|
a(href="/admin/survey") Manage Surveys
|
||||||
|
|
|
@ -1,4 +1,18 @@
|
||||||
|
@import '../../../frontend/stylesheets/core/variables.less';
|
||||||
|
|
||||||
.admin-panel-pagination {
|
.admin-panel-pagination {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.phase-badge {
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: @badge-border-radius;
|
||||||
|
font-size: @font-size-small;
|
||||||
|
font-weight: @badge-font-weight;
|
||||||
|
line-height: @badge-line-height;
|
||||||
|
color: @badge-color;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: center;
|
||||||
|
padding: 3px 7px;
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ QUEUES_REDIS_HOST=localhost
|
||||||
PUBSUB_REDIS_HOST=localhost
|
PUBSUB_REDIS_HOST=localhost
|
||||||
RATELIMITER_REDIS_HOST=localhost
|
RATELIMITER_REDIS_HOST=localhost
|
||||||
GCLOUD_2_REDIS_HOST=localhost
|
GCLOUD_2_REDIS_HOST=localhost
|
||||||
QUEUES_REDIS_HOST=localhost
|
|
||||||
POSTGRES_HOST=localhost
|
POSTGRES_HOST=localhost
|
||||||
MONGO_URL=mongodb://localhost/sharelatex
|
MONGO_URL=mongodb://localhost/sharelatex
|
||||||
SHARELATEX_LDAP_URL=ldap://localhost:22389
|
SHARELATEX_LDAP_URL=ldap://localhost:22389
|
||||||
|
|
|
@ -136,6 +136,9 @@
|
||||||
"bunyan": "^1.8.15",
|
"bunyan": "^1.8.15",
|
||||||
"cache-flow": "^1.7.4",
|
"cache-flow": "^1.7.4",
|
||||||
"celebrate": "^10.0.1",
|
"celebrate": "^10.0.1",
|
||||||
|
"chart.js": "^4.0.1",
|
||||||
|
"chartjs-adapter-moment": "^1.0.1",
|
||||||
|
"chartjs-plugin-datalabels": "^2.2.0",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"codemirror": "~5.33.0",
|
"codemirror": "~5.33.0",
|
||||||
"connect-redis": "^3.1.0",
|
"connect-redis": "^3.1.0",
|
||||||
|
@ -211,6 +214,7 @@
|
||||||
"qrcode": "^1.4.4",
|
"qrcode": "^1.4.4",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-bootstrap": "^0.33.1",
|
"react-bootstrap": "^0.33.1",
|
||||||
|
"react-chartjs-2": "^5.0.1",
|
||||||
"react-dnd": "^11.1.3",
|
"react-dnd": "^11.1.3",
|
||||||
"react-dnd-html5-backend": "^11.1.3",
|
"react-dnd-html5-backend": "^11.1.3",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
|
|
Loading…
Reference in a new issue