Adding Litmus Portal API docs (#2378)

* Adding Litmus Portal API doc

Signed-off-by: Raj Babu Das <raj.das@mayadata.io>

* Adding Litmus Portal API doc

Signed-off-by: Raj Babu Das <raj.das@mayadata.io>

* Adding Litmus Portal API doc

Signed-off-by: Raj Babu Das <raj.das@mayadata.io>
This commit is contained in:
Raj Babu Das 2020-12-15 20:59:06 +05:30 committed by GitHub
parent 4957c1c013
commit 1993b29e8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 12275 additions and 3 deletions

View File

@ -1,4 +1,5 @@
**/node_modules/
**/*.md
**/cypress/
**/geo.json
**/geo.json
**/public/api-doc

View File

@ -0,0 +1,638 @@
introspection: http://localhost:8080/query
servers:
- url: http://localhost:8080
description: Dev
- url: http://localhost:8080/query
description: Prod
info:
title: Litmus Portal API Documentation
description: |
Litmus Portal provides console and UI experience for managing, monitoring, and events around chaos workflows. Chaos workflows consist of a sequence of experiments run together to achieve the objective of introducing some kind of fault into an application or the Kubernetes platform.
domains:
- name: Cluster
description: |
Litmus Portal gives the ability to run chaos on remote Kubernetes cluster. Self cluster is automatically getting connected after submitting the welcome model. To connect an external cluster, use the following APIs for cluster operations. <br/>
User can access connected clusters via <b>targets</b> page of Litmus Portal.
usecases:
- name: Register Cluster
query: mutation.userClusterReg
description: |
User can make requests to connect their kubernetes cluster and get a token as response, that token can be used to get the subscriber manifest which needs to apply in their cluster.
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>platform_name</td>
<td>-</td>
<td>Optional</td>
</tr>
<tr>
<td>cluster_type</td>
<td>external/internal</td>
<td>Mandatory</td>
</tr>
<tr>
<td>agent_namespace</td>
<td>-</td>
<td>Optional</td>
</tr>
<tr>
<td>serviceaccount</td>
<td>-</td>
<td>Optional</td>
</tr>
<tr>
<td>agent_scope</td>
<td>cluster/namespace</td>
<td>Mandatory</td>
</tr>
<tr>
<td>agent_ns_exists</td>
<td>true/false</td>
<td>Mandatory</td>
</tr>
<tr>
<td>agent_sa_exists</td>
<td>true/false</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"cluster_name"</b>: "Litmus-cluster", <br/>
<b>"description"</b>: "New Litmus Portal Cluster",<br/>
<b>"platform_name"</b>: "AWS",<br/>
<b>"project_id"</b>: "5fd7d9212c9f32447e28317b",<br/>
<b>"cluster_type"</b>: "external",<br/>
<b>"agent_namespace"</b>: "",<br/>
<b>"agent_namespace"</b>: "",<br/>
<b>"agent_scope"</b>: cluster,<br/>
<b>"agent_ns_exists"</b>: false,<br/>
<b>"agent_sa_exists"</b>: false,
</p>
}
- name: List Cluster
query: query.getCluster
description: |
Returns a list of cluster with Litmus Portal. It includes pending, active and inactive clusters.
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>project_id</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>cluster_type</td>
<td>external/internal</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"project_id"</b>: "5fd7d9212c9f32447e28317b", <br/>
<b>"cluster_type"</b>: "external",<br/>
</p>
}
- name: Delete Cluster
query: mutation.deleteClusterReg
description: |
This query can be used to delete a cluster from litmus portal. It cannot be undone. <br/>
<b>Note:</b> User can access the details of deleted cluster inside MongoDB, which are being marked as removed.
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>cluster_id</td>
<td>-</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"cluster_id"</b>: "2df3212c9f32447e28317b", <br/>
</p>
}
- name: Chaos Workflow
description: |
Chaos workflows consist of a sequence of experiments run together to introduce chaos in the Kubernetes platform. <br/>
<b>Note:</b> Target cluster should be in active state before scheduling the workflow
usecases:
- name: Create ChaosWorkflow
query: mutation.createChaosWorkFlow
description: |
User can create chaosworkflow easily via the workflow page of the Litmus Portal dashboard.
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>workflow_manifest</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>cronSyntax</td>
<td>-</td>
<td>Optional</td>
</tr>
<tr>
<td>workflow_name</td>
<td>external/internal</td>
<td>Mandatory</td>
</tr>
<tr>
<td>workflow_description</td>
<td>-</td>
<td>Optional</td>
</tr>
<tr>
<td>isCustomWorkflow</td>
<td>true/false</td>
<td>Madatory</td>
</tr>
<tr>
<td>project_id</td>
<td></td>
<td>Mandatory</td>
</tr>
<tr>
<td>cluster_id</td>
<td></td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"workflow_name"</b>: "Pod-networkloss-chaos", <br/>
<b>"workflow_manifest"</b>: "{ apiVersion: v1 ......}",<br/>
<b>"cronSyntax"</b>: "***/2",<br/>
<b>"project_id"</b>: "5fd7d9212c9f32447e28317b",<br/>
<b>"cluster_id"</b>: "3gr3f492146f53d4g3e283re",<br/>
<b>"workflow_description"</b>: "Pod networkloss-experiment",<br/>
<b>"isCustomWorkflow"</b>: false,<br/>
</p>
}
- name: List ChaosWorkflow
query: query.ListWorkflow
description: |
Returns a list of chaos workflow and details of particular using a same endpoint. It can fetch both cron and non-cron workflow present in the Litmus Portal. <br/>
User can get a particular workflow by appending <b>workflow_id</b> inside an array of <b>workflow_ids</b>, if the array is empty it will return a list of chaos workflow.
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>project_id</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>workflow_ids</td>
<td>[]</td>
<td>Optional</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"project_id"</b>: "5fd7d9212c9f32447e28317b", <br/>
<b>"workflow_ids"</b>: ["3gr3f492146f53d4g3e283re"],<br/>
</p>
}
- name: Update ChaosWorkflow
query: mutation.updateChaosWorkflow
description: |
Update the specified chaos workflow by setting the values of the parameters passed. Any parameters not provided will change with its empty value.
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>workflow_id</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>cronSyntax</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>workflow_name</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>workflow_description</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>isCustomWorkflow</td>
<td>true/false</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"workflow_id"</b>: "5fd7d9212c9f32447e28317b", <br/>
<b>"cronSyntax"</b>: "****",<br/>
<b>"workflow_name"</b>: "New-network-chaos",<br/>
<b>"workflow_description"</b>: "Update Chaos workflow",<br/>
<b>"isCustomWorkflow"</b>: false<br/>
</p>
}
- name: Delete ChaosWorkflow
query: mutation.deleteChaosWorkflow
description: |
Delete chaos workflow will permanently delete schedule workflow from the cluster. It cannot be undone.
<b>Note:</b> User can access the details of deleted workflow inside MongoDB, which are being marked as removed.
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>workflowid</td>
<td>-</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"workflowid"</b>: "2df3212c9f32447e28317b", <br/>
</p>
}
- name: MyHub
description: MyHub constructs workflow from a set of experiments from Chaos Hub or the Git Repo. There is a public hub which get cloned during the installation by default.
usecases:
- name: Add Myhub
query: mutation.addMyHub
description: |
User can add myhub easily via the myhub page of the Litmus Portal dashboard. After adding myhub, it will clone the git repository which has the chaos charts.
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>RepoURL</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>RepoBranch</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>HubName</td>
<td>-</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"RepoURL"</b>: "https://github.com/litmuschaos/chaos-charts", <br/>
<b>"RepoBranch"</b>: "master",<br/>
<b>"HubName"</b>: "my-chaos-hub",<br/>
</p>
}
- name: List MyHub
query: query.getHubStatus
description: |
Returns a list of myhub connected with Litmus Portal
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>projectID</td>
<td>-</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"projectID"</b>: "5fd7d9212c9f32447e28317b", <br/>
</p>
}
- name: Sync MyHub
query: mutation.syncHub
description: |
Sync hub will pull the latest commits from the git repository.
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>projectID</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>HubName</td>
<td>-</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"project_id"</b>: "5fd7d9212c9f32447e28317b", <br/>
<b>"HubName"</b>: "my-chaos-hub", <br/>
</p>
}
- name: User Management
description: User Management APIs manages user accessibility with Litmus Portal
usecases:
- name: Add User
description: |
Admin can add their team members via the user management panel of settings page. After that, user can login with their credentials to litmus portal.
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>username</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>email</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>company_name</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>name</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>project_name</td>
<td>-</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"username"</b>: "litmus-user", <br/>
<b>"email"</b>: "litmuschaos@gmail.com", <br/>
<b>"company_name"</b>: "CNCF", <br/>
<b>"name"</b>: "Litmus User", <br/>
<b>"project_name"</b>: "my-project", <br/>
</p>
}
query: mutation.createUser
- name: List User
query: query.users
description: |
Returns a list of user within the Litmus Portal
- name: Get User
query: query.getUser
description: |
Returns a specified user within the Litmus Portal
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>username</td>
<td>-</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"username"</b>: "litmus-user", <br/>
</p>
}
- name: Update User
query: muatation.updateUser
description: |
User can update its details details by providing the following parameters:
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>id</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>name</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>email</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>company_name</td>
<td>-</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"id"</b>: "5fd7d9212c9f32447e28317b", <br/>
<b>"name"</b>: "litmus-user", <br/>
<b>"email"</b>: "litmususer@yahoo.com", <br/>
<b>"company_name"</b>: "CNCF", <br/>
</p>
}
- name: Send Invitation
query: mutation.sendInvitation
description: |
Admin can invite registered user to their project and assign them with viewer or editor access. Following are the parameters for this mutation:
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>project_id</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>user_name</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>role</td>
<td>Viewer/Editor</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"project_id"</b>: "5fd7d9212c9f32447e28317b", <br/>
<b>"username"</b>: "litmus-user", <br/>
<b>"role"</b>: "Editor", <br/>
</p>
}
- name: Accept Invitation
query: mutation.acceptInvitation
description: |
User can accept the invitation by invoking this endpoint.
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>project_id</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>user_name</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>role</td>
<td>Viewer/Editor</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"project_id"</b>: "5fd7d9212c9f32447e28317b", <br/>
<b>"username"</b>: "litmus-user", <br/>
<b>"role"</b>: "Viewer", <br/>
</p>
}
- name: Decline Invitation
query: mutation.declineInvitation
description: |
User can decline the invitation by invoking this endpoint.
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>project_id</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>user_name</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>role</td>
<td>Viewer/Editor</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"project_id"</b>: "5fd7d9212c9f32447e28317b", <br/>
<b>"username"</b>: "litmus-user", <br/>
<b>"role"</b>: "Viewer", <br/>
</p>
}
- name: Remove Invitation
query: mutation.declineInvitation
description: |
User can remove the invitation by invoking this endpoint.
<table>
<tr>
<th>Field</th>
<th>Possible values</th>
<th>Mandatory/Optional</th>
</tr>
<tr>
<td>project_id</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>user_name</td>
<td>-</td>
<td>Mandatory</td>
</tr>
<tr>
<td>role</td>
<td>Viewer/Editor</td>
<td>Mandatory</td>
</tr>
</table>
<h6>Example Body:</h6>
{<br/>
<p style="margin-left: 40px">
<b>"project_id"</b>: "5fd7d9212c9f32447e28317b", <br/>
<b>"username"</b>: "litmus-user", <br/>
<b>"role"</b>: "Viewer", <br/>
</p>
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,242 @@
$(function() {
// $(document).foundation();
var $sidebar = $('#sidebar');
if ($sidebar.length) {
var $docs = $('#docs');
var $nav = $sidebar.find('nav');
//
// Setup sidebar navigation
var traverse = new Traverse($nav, {
threshold: 10,
barOffset: $sidebar.position().top
});
$nav.on('update.traverse', function(event, element) {
$nav.find('section').removeClass('expand');
var $section = element.parents('section:first');
if ($section.length) {
$section.addClass('expand');
}
});
//
// Bind the drawer layout
var $drawerLayout = $('.drawer-layout'),
$drawer = $drawerLayout.find('.drawer'),
closeDrawer = function() {
$drawer.removeClass('slide-right slide-left');
$drawer.find('.drawer-overlay').remove();
$drawerLayout.removeClass('drawer-open drawer-slide-left-large drawer-slide-right-large');
return false;
};
// Drawer open buttons
$drawerLayout.find('[data-drawer-slide]').click(function(e) {
var $this = $(this),
direction = $this.data('drawer-slide');
$drawerLayout.addClass('drawer-open');
$drawer.addClass('slide-' + direction);
var $overlay = $('<a href="#" class="drawer-overlay"></a>')
$drawer.append($overlay);
$overlay.click(closeDrawer);
return false;
});
// Drawer close buttons
$drawerLayout.find('[data-drawer-close]').click(closeDrawer);
}
});
/**
* Creates a new instance of Traverse.
* @class
* @fires Traverse#init
* @param {Object} element - jQuery object to add the trigger to.
* @param {Object} options - Overrides to the default plugin settings.
*/
function Traverse(element, options) {
this.$element = element;
this.options = $.extend({}, Traverse.defaults, this.$element.data(), options);
this._init();
}
/**
* Default settings for plugin
*/
Traverse.defaults = {
/**
* Amount of time, in ms, the animated scrolling should take between locations.
* @option
* @example 500
*/
animationDuration: 500,
/**
* Animation style to use when scrolling between locations.
* @option
* @example 'ease-in-out'
*/
animationEasing: 'linear',
/**
* Number of pixels to use as a marker for location changes.
* @option
* @example 50
*/
threshold: 50,
/**
* Class applied to the active locations link on the traverse container.
* @option
* @example 'active'
*/
activeClass: 'active',
/**
* Allows the script to manipulate the url of the current page, and if supported, alter the history.
* @option
* @example true
*/
deepLinking: false,
/**
* Number of pixels to offset the scroll of the page on item click if using a sticky nav bar.
* @option
* @example 25
*/
barOffset: 0
};
/**
* Initializes the Traverse plugin and calls functions to get equalizer functioning on load.
* @private
*/
Traverse.prototype._init = function() {
var id = this.$element[0].id, // || Foundation.GetYoDigits(6, 'traverse'),
_this = this;
this.$targets = $('[data-traverse-target]');
this.$links = this.$element.find('a');
this.$element.attr({
'data-resize': id,
'data-scroll': id,
'id': id
});
this.$active = $();
this.scrollPos = parseInt(window.pageYOffset, 10);
this._events();
};
/**
* Calculates an array of pixel values that are the demarcation lines between locations on the page.
* Can be invoked if new elements are added or the size of a location changes.
* @function
*/
Traverse.prototype.calcPoints = function(){
var _this = this,
body = document.body,
html = document.documentElement;
this.points = [];
this.winHeight = Math.round(Math.max(window.innerHeight, html.clientHeight));
this.docHeight = Math.round(Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight));
this.$targets.each(function(){
var $tar = $(this),
pt = $tar.offset().top; // Math.round($tar.offset().top - _this.options.threshold);
$tar.targetPoint = pt;
_this.points.push(pt);
});
};
/**
* Initializes events for Traverse.
* @private
*/
Traverse.prototype._events = function() {
var _this = this,
$body = $('html, body'),
opts = {
duration: _this.options.animationDuration,
easing: _this.options.animationEasing
};
$(window).one('load', function(){
_this.calcPoints();
_this._updateActive();
$(this).resize(function(e) {
_this.reflow();
}).scroll(function(e) {
_this._updateActive();
});
})
this.$element.on('click', 'a[href^="#"]', function(e) { //'click.zf.traverse'
e.preventDefault();
var arrival = this.getAttribute('href').replace(".", "\\."),
scrollPos = $(arrival).offset().top - _this.options.barOffset; // - _this.options.threshold / 2 - _this.options.barOffset;
$body.stop(true).animate({
scrollTop: scrollPos
}, opts);
});
};
/**
* Calls necessary functions to update Traverse upon DOM change
* @function
*/
Traverse.prototype.reflow = function(){
this.calcPoints();
this._updateActive();
};
/**
* Updates the visibility of an active location link,
* and updates the url hash for the page, if deepLinking enabled.
* @private
* @function
* @fires Traverse#update
*/
Traverse.prototype._updateActive = function(){
var winPos = parseInt(window.pageYOffset, 10),
curIdx;
if(winPos + this.winHeight === this.docHeight){ curIdx = this.points.length - 1; }
else if(winPos < this.points[0]){ curIdx = 0; }
else{
var isDown = this.scrollPos < winPos,
_this = this,
curVisible = this.points.filter(function(p, i){
return isDown ?
p <= (winPos + _this.options.barOffset + _this.options.threshold) :
(p - (_this.options.barOffset + _this.options.threshold)) <= winPos;
// p <= (winPos - (offset - _this.options.threshold)) :
// (p - (-offset + _this.options.threshold)) <= winPos;
});
curIdx = curVisible.length ? curVisible.length - 1 : 0;
}
var $prev = this.$active;
var $next = this.$links.eq(curIdx);
this.$active.removeClass(this.options.activeClass);
this.$active = $next.addClass(this.options.activeClass);
if(this.options.deepLinking){
var hash = this.$active[0].getAttribute('href');
if(window.history.pushState){
window.history.pushState(null, null, hash);
}else{
window.location.hash = hash;
}
}
this.scrollPos = winPos;
// Fire event if the active element was changed
var changed = $prev[0] !== $next[0];
if (changed) {
this.$element.trigger('update.traverse', [this.$active]);
}
};

View File

@ -0,0 +1 @@
function Traverse(t,e){this.$element=t,this.options=$.extend({},Traverse.defaults,this.$element.data(),e),this._init()}$(function(){var i,s,a,n,t=$("#sidebar");t.length&&($("#docs"),new Traverse(i=t.find("nav"),{threshold:10,barOffset:t.position().top}),i.on("update.traverse",function(t,e){i.find("section").removeClass("expand");e=e.parents("section:first");e.length&&e.addClass("expand")}),s=$(".drawer-layout"),a=s.find(".drawer"),n=function(){return a.removeClass("slide-right slide-left"),a.find(".drawer-overlay").remove(),s.removeClass("drawer-open drawer-slide-left-large drawer-slide-right-large"),!1},s.find("[data-drawer-slide]").click(function(t){var e=$(this).data("drawer-slide");s.addClass("drawer-open"),a.addClass("slide-"+e);e=$('<a href="#" class="drawer-overlay"></a>');return a.append(e),e.click(n),!1}),s.find("[data-drawer-close]").click(n))}),Traverse.defaults={animationDuration:500,animationEasing:"linear",threshold:50,activeClass:"active",deepLinking:!1,barOffset:0},Traverse.prototype._init=function(){var t=this.$element[0].id;this.$targets=$("[data-traverse-target]"),this.$links=this.$element.find("a"),this.$element.attr({"data-resize":t,"data-scroll":t,id:t}),this.$active=$(),this.scrollPos=parseInt(window.pageYOffset,10),this._events()},Traverse.prototype.calcPoints=function(){var i=this,t=document.body,e=document.documentElement;this.points=[],this.winHeight=Math.round(Math.max(window.innerHeight,e.clientHeight)),this.docHeight=Math.round(Math.max(t.scrollHeight,t.offsetHeight,e.clientHeight,e.scrollHeight,e.offsetHeight)),this.$targets.each(function(){var t=$(this),e=t.offset().top;t.targetPoint=e,i.points.push(e)})},Traverse.prototype._events=function(){var e=this,i=$("html, body"),s={duration:e.options.animationDuration,easing:e.options.animationEasing};$(window).one("load",function(){e.calcPoints(),e._updateActive(),$(this).resize(function(t){e.reflow()}).scroll(function(t){e._updateActive()})}),this.$element.on("click",'a[href^="#"]',function(t){t.preventDefault();t=this.getAttribute("href").replace(".","\\."),t=$(t).offset().top-e.options.barOffset;i.stop(!0).animate({scrollTop:t},s)})},Traverse.prototype.reflow=function(){this.calcPoints(),this._updateActive()},Traverse.prototype._updateActive=function(){var i,s,a=parseInt(window.pageYOffset,10);t=a+this.winHeight===this.docHeight?this.points.length-1:a<this.points[0]?0:(i=this.scrollPos<a,(n=(s=this).points.filter(function(t,e){return i?t<=a+s.options.barOffset+s.options.threshold:t-(s.options.barOffset+s.options.threshold)<=a})).length?n.length-1:0);var t,e=this.$active,n=this.$links.eq(t);this.$active.removeClass(this.options.activeClass),this.$active=n.addClass(this.options.activeClass),this.options.deepLinking&&(t=this.$active[0].getAttribute("href"),window.history.pushState?window.history.pushState(null,null,t):window.location.hash=t),this.scrollPos=a,e[0]!==n[0]&&this.$element.trigger("update.traverse",[this.$active])};

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -44,7 +44,8 @@ quickActionCard:
quickActions: Quick Actions
inviteTeamMember: Invite a team member
quickSurvey: Take a quick survey
readDocs: Read The Litmus docs
readDocs: Read the Litmus docs
readAPIDocs: Read the Litmus Portal API docs
customWorkflowCard:
customWorkflow: Create your own workflow

View File

@ -19,6 +19,7 @@ const QuickActionCard = () => {
const userRole = useSelector((state: RootState) => state.userData.userRole);
const tabs = useActions(TabActions);
const { t } = useTranslation();
const apiDocsUrl = `${window.location.href}api-doc`;
return (
<div data-cy="quickActionCardComponent" className={classes.quickActionCard}>
@ -71,6 +72,14 @@ const QuickActionCard = () => {
{t('quickActionCard.readDocs')}
</a>
</QuickActionItems>
<QuickActionItems>
<div className={classes.imgDiv}>
<img src="./icons/docs.png" alt="docs" />
</div>
<a href={apiDocsUrl} className={classes.listItem} target="_">
{t('quickActionCard.readAPIDocs')}
</a>
</QuickActionItems>
</List>
</Card>
</div>

View File

@ -43,10 +43,24 @@ interface RoutesProps {
const Routes: React.FC<RoutesProps> = ({ isOwner, isProjectAvailable }) => {
const classes = useStyles();
const iframe = () => {
return {
__html:
'<iframe src="/api-doc/index.html" style="width:100%; height:100vh;"></iframe>',
};
};
if (getToken() === '') {
return (
<div className={classes.content}>
<Switch>
<Route
exact
path="/api-doc"
component={() => {
return <div dangerouslySetInnerHTML={iframe()} />;
}}
/>
<Route exact path="/login" component={LoginPage} />
<Route path="/" render={() => <Redirect to="/login" />} />
</Switch>
@ -59,6 +73,13 @@ const Routes: React.FC<RoutesProps> = ({ isOwner, isProjectAvailable }) => {
<div className={classes.content}>
<Switch>
<Route exact path="/" component={HomePage} />
<Route
exact
path="/api-doc"
component={() => {
return <div dangerouslySetInnerHTML={iframe()} />;
}}
/>
<Route path="/" render={() => <Redirect to="/" />} />
</Switch>
</div>
@ -71,7 +92,13 @@ const Routes: React.FC<RoutesProps> = ({ isOwner, isProjectAvailable }) => {
<Route exact path="/" component={HomePage} />
<Route exact path="/workflows" component={Workflows} />
<Route exact path="/create-workflow" component={CreateWorkflow} />
<Route
exact
path="/api-doc"
component={() => {
return <div dangerouslySetInnerHTML={iframe()} />;
}}
/>
{/* Redirects */}
<Redirect exact path="/login" to="/" />
<Redirect exact path="/workflows/details" to="/workflows" />