Commit 6609dbff by Torkel Ödegaard

ux: sidenav fixes and dashboard search changes

parent a4da0adf
.sidemenu {
display: flex;
flex-flow: column;
flex-direction: column;
width: $side-menu-width;
background-color: $side-menu-bg;
z-index: 1;
a:focus {
text-decoration: none;
}
}
.sidemenu__top {
flex-grow: 1;
}
.sidemenu__bottom {
padding-bottom: $spacer;
}
.sidemenu-item {
position: relative;
@include left-brand-border();
&.active,
&:hover {
background-color: $side-menu-item-hover-bg;
@include left-brand-border-gradient();
.dropdown-menu {
margin: 0;
display: block;
opacity: 0;
top: 0px;
// important to overlap it otherwise it can be hidden
// again by the mouse getting outside the hover space
left: $side-menu-width - 2px;
@include animation('dropdown-anim 100ms ease-in-out 100ms forwards');
z-index: 1;
}
}
}
.dropup.sidemenu-item:hover .dropdown-menu {
top: auto !important;
}
.sidemenu-link {
color: $link-color;
line-height: 42px;
padding: 0px 10px 0px 10px;
display: block;
position: relative;
font-size: 16px;
border: 1px solid transparent;
img {
border-radius: 50%;
width: 28px;
height: 28px;
box-shadow: 0 0 14px 2px rgba(255,255,255, 0.05);
}
}
@include keyframes(dropdown-anim) {
0% {
opacity: 0;
//transform: translate3d(-5%,0,0);
}
100% {
opacity: 1;
//transform: translate3d(0,0,0);
}
}
.icon-circle {
width: 35px;
height: 35px;
display: inline-block;
i {
color: $link-color;
opacity: .7;
position: relative;
left: 3px;
font-size: 130%;
}
.fa {
top: 2px;
}
.icon-gf {
top: 5px;
}
img {
left: 3px;
position: relative;
}
}
.side-menu-header {
padding: 10px 10px 10px 20px;
white-space: nowrap;
background-color: $side-menu-item-hover-bg;
font-size: 17px;
}
li.sidemenu-org-switcher {
border-bottom: 1px solid $dropdownDividerBottom;
}
.sidemenu-org-switcher__org-name {
font-size: $font-size-base;
}
.sidemenu-org-switcher__org-current {
font-size: $font-size-xs;
color: $text-color-weak;
}
.sidemenu-org-switcher__switch {
font-size: $font-size-sm;
padding-left: 1.5rem;
display: flex;
align-items: center;
i.fa > {
margin-right: 5px;
top: 0;
}
}
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
"dependencies": { "dependencies": {
"eventemitter3": "^2.0.2", "eventemitter3": "^2.0.2",
"gaze": "^1.1.2", "gaze": "^1.1.2",
"gemini-scrollbar": "^1.5.2", "gemini-scrollbar": "https://github.com/grafana/gemini-scrollbar#grafana",
"grunt-jscs": "3.0.1", "grunt-jscs": "3.0.1",
"grunt-sass-lint": "^0.2.2", "grunt-sass-lint": "^0.2.2",
"grunt-sync": "^0.6.2", "grunt-sync": "^0.6.2",
......
...@@ -12,6 +12,10 @@ export function geminiScrollbar() { ...@@ -12,6 +12,10 @@ export function geminiScrollbar() {
autoshow: false, autoshow: false,
element: elem[0] element: elem[0]
}).create(); }).create();
scope.$on('$destroy', () => {
myScrollbar.destroy();
});
} }
}; };
} }
......
...@@ -40,35 +40,38 @@ ...@@ -40,35 +40,38 @@
</div> </div>
<div class="search-dropdown" ng-class="{'search-dropdown--fade-in': ctrl.openCompleted}"> <div class="search-dropdown" ng-class="{'search-dropdown--fade-in': ctrl.openCompleted}">
<div class="search-results-container" ng-if="ctrl.tagsMode"> <div gemini-scrollbar>
<div ng-repeat="tag in ctrl.results" class="pointer" style="width: 180px; float: left;" <div class="search-results-container" ng-if="ctrl.tagsMode">
ng-class="{'selected': $index === ctrl.selectedIndex }" <div ng-repeat="tag in ctrl.results" class="pointer" style="width: 180px; float: left;"
ng-click="ctrl.filterByTag(tag.term, $event)"> ng-class="{'selected': $index === ctrl.selectedIndex }"
<a class="search-result-tag label label-tag" tag-color-from-name="tag.term"> ng-click="ctrl.filterByTag(tag.term, $event)">
<i class="fa fa-tag"></i> <a class="search-result-tag label label-tag" tag-color-from-name="tag.term">
<span>{{tag.term}} &nbsp;({{tag.count}})</span> <i class="fa fa-tag"></i>
</a> <span>{{tag.term}} &nbsp;({{tag.count}})</span>
</a>
</div>
</div> </div>
</div>
<div class="search-results-container" ng-if="!ctrl.tagsMode"> <div class="search-results-container" ng-if="!ctrl.tagsMode">
<h6 ng-hide="ctrl.results.length">No dashboards matching your query were found.</h6> <h6 ng-hide="ctrl.results.length">No dashboards matching your query were found.</h6>
<div ng-repeat="row in ctrl.results"> <div ng-repeat="row in ctrl.results">
<a class="search-item search-item--{{::row.type}}" ng-class="{'selected': $index == ctrl.selectedIndex}" ng-href="{{row.url}}"> <a class="search-item search-item--{{::row.type}}" ng-class="{'selected': $index == ctrl.selectedIndex}" ng-href="{{row.url}}">
<span class="search-result-tags"> <span class="search-result-tags">
<span ng-click="ctrl.filterByTag(tag, $event)" ng-repeat="tag in row.tags" tag-color-from-name="tag" class="label label-tag"> <span ng-click="ctrl.filterByTag(tag, $event)" ng-repeat="tag in row.tags" tag-color-from-name="tag" class="label label-tag">
{{tag}} {{tag}}
</span> </span>
<i class="fa" ng-class="{'fa-star': row.isStarred, 'fa-star-o': !row.isStarred}"></i> <i class="fa" ng-class="{'fa-star': row.isStarred, 'fa-star-o': !row.isStarred}"></i>
</span> </span>
<span class="search-result-link"> <span class="search-result-link">
<i class="fa search-result-icon"></i> <i class="fa search-result-icon"></i>
{{::row.title}} {{::row.title}}
</span> </span>
</a> </a>
</div> </div>
</div>
</div>
</div> </div>
</div> </div>
...@@ -83,33 +83,6 @@ ...@@ -83,33 +83,6 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div ng-if="editor.index == 1">
<h5 class="section-heading">Rows settings</h5>
<div class="gf-form-group">
<div class="gf-form-inline" ng-repeat="row in dashboard.rows">
<div class="gf-form">
<span class="gf-form-label">Title</span>
<input type="text" class="gf-form-input max-width-14" ng-model='row.title'></input>
</div>
<gf-form-switch class="gf-form" label="Show title" checked="row.showTitle" switch-class="max-width-6"></gf-form-switch>
<div class="gf-form">
<button class="btn btn-inverse gf-form-btn" ng-click="_.move(dashboard.rows,$index,$index-1)">
<i ng-class="{'invisible': $first}" class="fa fa-arrow-up"></i>
</button>
<button class="btn btn-inverse gf-from-btn" ng-click="_.move(dashboard.rows,$index,$index+1)">
<i ng-class="{'invisible': $last}" class="fa fa-arrow-down"></i>
</button>
<button class="btn btn-inverse gf-form-btn" ng-click="dashboard.rows = _.without(dashboard.rows,row)">
<i class="fa fa-trash"></i>
</button>
</div>
</div>
</div>
</div> </div>
<div ng-if="editor.index == 2"> <div ng-if="editor.index == 2">
......
...@@ -47,7 +47,7 @@ export class OrgUsersCtrl { ...@@ -47,7 +47,7 @@ export class OrgUsersCtrl {
} else if (config.disableLoginForm) { } else if (config.disableLoginForm) {
return "Add Users"; return "Add Users";
} else { } else {
return "Add or Invite"; return "Add";
} }
} }
......
...@@ -26,12 +26,12 @@ ...@@ -26,12 +26,12 @@
</a> </a>
</li> </li>
<li class="gf-tabs-item"> <li class="gf-tabs-item">
<a class="gf-tabs-link" ng-click="ctrl.editor.index = 0" ng-class="{active: ctrl.editor.index === 1}"> <a class="gf-tabs-link" ng-click="ctrl.editor.index = 1" ng-class="{active: ctrl.editor.index === 1}">
Groups (0) Groups (0)
</a> </a>
</li> </li>
<li class="gf-tabs-item" ng-show="ctrl.showInviteUI"> <li class="gf-tabs-item" ng-show="ctrl.pendingInvites.length">
<a class="gf-tabs-link" ng-click="ctrl.editor.index = 1" ng-class="{active: ctrl.editor.index === 2}"> <a class="gf-tabs-link" ng-click="ctrl.editor.index = 2" ng-class="{active: ctrl.editor.index === 2}">
Pending Invitations ({{ctrl.pendingInvites.length}}) Pending Invitations ({{ctrl.pendingInvites.length}})
</a> </a>
</li> </li>
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
</table> </table>
</div> </div>
<div ng-if="ctrl.editor.index === 1 && ctrl.showInviteUI"> <div ng-if="ctrl.editor.index === 2">
<table class="filter-table form-inline"> <table class="filter-table form-inline">
<thead> <thead>
<tr> <tr>
......
...@@ -99,7 +99,6 @@ function panelHeader($compile) { ...@@ -99,7 +99,6 @@ function panelHeader($compile) {
menuScope = scope.$new(); menuScope = scope.$new();
let menuHtml = createMenuTemplate(scope.ctrl); let menuHtml = createMenuTemplate(scope.ctrl);
console.log(menuHtml);
menuElem.html(menuHtml); menuElem.html(menuHtml);
$compile(menuElem)(menuScope); $compile(menuElem)(menuScope);
......
<div class="scroll-canvas"> <div class="scroll-canvas">
<navbar model="ctrl.navModel"></navbar> <div gemini-scrollbar>
<div class="page-container"> <navbar model="ctrl.navModel"></navbar>
<div class="page-header"> <div class="page-container">
<page-h1 model="ctrl.navModel"></page-h1> <div class="page-header">
<page-h1 model="ctrl.navModel"></page-h1>
<div class="page-header-tabs" ng-show="ctrl.hasDashboards"> <div class="page-header-tabs" ng-show="ctrl.hasDashboards">
<ul class="gf-tabs"> <ul class="gf-tabs">
<li class="gf-tabs-item"> <li class="gf-tabs-item">
<a class="gf-tabs-link" ng-click="ctrl.tabIndex = 0" ng-class="{active: ctrl.tabIndex === 0}"> <a class="gf-tabs-link" ng-click="ctrl.tabIndex = 0" ng-class="{active: ctrl.tabIndex === 0}">
Config Config
</a> </a>
</li> </li>
<li class="gf-tabs-item"> <li class="gf-tabs-item">
<a class="gf-tabs-link" ng-click="ctrl.tabIndex = 1" ng-class="{active: ctrl.tabIndex === 1}"> <a class="gf-tabs-link" ng-click="ctrl.tabIndex = 1" ng-class="{active: ctrl.tabIndex === 1}">
Dashboards Dashboards
</a> </a>
</li> </li>
</ul> </ul>
</div>
</div> </div>
</div>
<div ng-if="ctrl.tabIndex === 0" class="tab-content"> <div ng-if="ctrl.tabIndex === 0" class="tab-content">
<form name="ctrl.editForm" ng-if="ctrl.current"> <form name="ctrl.editForm" ng-if="ctrl.current">
<div class="gf-form-group"> <div class="gf-form-group">
<div class="gf-form-inline"> <div class="gf-form-inline">
<div class="gf-form max-width-30"> <div class="gf-form max-width-30">
<span class="gf-form-label width-7">Name</span> <span class="gf-form-label width-7">Name</span>
<input class="gf-form-input max-width-23" type="text" ng-model="ctrl.current.name" placeholder="name" required> <input class="gf-form-input max-width-23" type="text" ng-model="ctrl.current.name" placeholder="name" required>
<info-popover offset="0px -135px" mode="right-absolute"> <info-popover offset="0px -135px" mode="right-absolute">
The name is used when you select the data source in panels. The name is used when you select the data source in panels.
The <em>Default</em> data source is preselected in new The <em>Default</em> data source is preselected in new
panels. panels.
</info-popover> </info-popover>
</div>
<gf-form-switch class="gf-form" label="Default" checked="ctrl.current.isDefault" switch-class="max-width-6"></gf-form-switch>
</div> </div>
<gf-form-switch class="gf-form" label="Default" checked="ctrl.current.isDefault" switch-class="max-width-6"></gf-form-switch>
</div>
<div class="gf-form"> <div class="gf-form">
<span class="gf-form-label width-7">Type</span> <span class="gf-form-label width-7">Type</span>
<div class="gf-form-select-wrapper max-width-23"> <div class="gf-form-select-wrapper max-width-23">
<select class="gf-form-input" ng-model="ctrl.current.type" ng-options="v.id as v.name for v in ctrl.types" ng-change="ctrl.typeChanged()"></select> <select class="gf-form-input" ng-model="ctrl.current.type" ng-options="v.id as v.name for v in ctrl.types" ng-change="ctrl.typeChanged()"></select>
</div>
</div> </div>
</div> </div>
</div>
<div class="alert alert-info gf-form-group" ng-if="ctrl.datasourceMeta.state === 'alpha'"> <div class="alert alert-info gf-form-group" ng-if="ctrl.datasourceMeta.state === 'alpha'">
This plugin is marked as being in alpha state, which means it is in early development phase and This plugin is marked as being in alpha state, which means it is in early development phase and
updates will include breaking changes. updates will include breaking changes.
</div> </div>
<rebuild-on-change property="ctrl.datasourceMeta.id"> <rebuild-on-change property="ctrl.datasourceMeta.id">
<plugin-component type="datasource-config-ctrl"> <plugin-component type="datasource-config-ctrl">
</plugin-component> </plugin-component>
</rebuild-on-change> </rebuild-on-change>
<div ng-if="ctrl.testing" class="gf-form-group"> <div ng-if="ctrl.testing" class="gf-form-group">
<h5 ng-show="!ctrl.testing.done">Testing.... <i class="fa fa-spiner fa-spin"></i></h5> <h5 ng-show="!ctrl.testing.done">Testing.... <i class="fa fa-spiner fa-spin"></i></h5>
<div class="alert-{{ctrl.testing.status}} alert"> <div class="alert-{{ctrl.testing.status}} alert">
<div class="alert-title">{{ctrl.testing.title}}</div> <div class="alert-title">{{ctrl.testing.title}}</div>
<div ng-bind='ctrl.testing.message'></div> <div ng-bind='ctrl.testing.message'></div>
</div>
</div> </div>
</div>
<div class="gf-form-button-row"> <div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-show="ctrl.isNew" ng-click="ctrl.saveChanges()">Add</button> <button type="submit" class="btn btn-success" ng-show="ctrl.isNew" ng-click="ctrl.saveChanges()">Add</button>
<button type="submit" class="btn btn-success" ng-show="!ctrl.isNew" ng-click="ctrl.saveChanges()">Save &amp; Test</button> <button type="submit" class="btn btn-success" ng-show="!ctrl.isNew" ng-click="ctrl.saveChanges()">Save &amp; Test</button>
<button type="submit" class="btn btn-danger" ng-show="!ctrl.isNew" ng-click="ctrl.delete()"> <button type="submit" class="btn btn-danger" ng-show="!ctrl.isNew" ng-click="ctrl.delete()">
Delete Delete
</button> </button>
<a class="btn btn-link" href="datasources">Cancel</a> <a class="btn btn-link" href="datasources">Cancel</a>
</div> </div>
</form> </form>
</div> </div>
<div ng-if="ctrl.tabIndex === 1" class="tab-content"> <div ng-if="ctrl.tabIndex === 1" class="tab-content">
<dashboard-import-list plugin="ctrl.datasourceMeta" datasource="ctrl.current"></dashboard-import-list> <dashboard-import-list plugin="ctrl.datasourceMeta" datasource="ctrl.current"></dashboard-import-list>
</div> </div>
</div>
</div> </div>
</div> </div>
<div class="scroll-canvas"> <div class="scroll-canvas">
<navbar model="ctrl.navModel"></navbar> <div gemini-scrollbar>
<div class="page-container"> <navbar model="ctrl.navModel"></navbar>
<div class="page-header"> <div class="page-container">
<page-h1 model="ctrl.navModel"></page-h1> <div class="page-header">
<page-h1 model="ctrl.navModel"></page-h1>
<a class="page-header__cta btn btn-success" href="datasources/new"> <a class="page-header__cta btn btn-success" href="datasources/new">
<i class="fa fa-plus"></i> <i class="fa fa-plus"></i>
Add data source Add data source
</a> </a>
</div> </div>
<section class="card-section" layout-mode> <section class="card-section" layout-mode>
<layout-selector></layout-selector> <layout-selector></layout-selector>
<ol class="card-list" > <ol class="card-list" >
<li class="card-item-wrapper" ng-repeat="ds in ctrl.datasources"> <li class="card-item-wrapper" ng-repeat="ds in ctrl.datasources">
<a class="card-item" href="datasources/edit/{{ds.id}}/"> <a class="card-item" href="datasources/edit/{{ds.id}}/">
<div class="card-item-header"> <div class="card-item-header">
<div class="card-item-type"> <div class="card-item-type">
{{ds.type}} {{ds.type}}
</div> </div>
</div> </div>
<div class="card-item-body"> <div class="card-item-body">
<figure class="card-item-figure"> <figure class="card-item-figure">
<img ng-src="{{ds.typeLogoUrl}}"> <img ng-src="{{ds.typeLogoUrl}}">
</figure> </figure>
<div class="card-item-details"> <div class="card-item-details">
<div class="card-item-name"> <div class="card-item-name">
{{ds.name}} {{ds.name}}
<span ng-if="ds.isDefault"> <span ng-if="ds.isDefault">
<span class="btn btn-secondary btn-mini">default</span> <span class="btn btn-secondary btn-mini">default</span>
</span> </span>
</div> </div>
<div class="card-item-sub-name"> <div class="card-item-sub-name">
{{ds.url}} {{ds.url}}
</div> </div>
</div> </div>
</div> </div>
</a> </a>
</li> </li>
</ol> </ol>
</section> </section>
<div ng-if="ctrl.datasources.length === 0"> <div ng-if="ctrl.datasources.length === 0">
<em>No data sources defined</em> <em>No data sources defined</em>
</div> </div>
</div> </div>
</div>
</div> </div>
<div dash-class ng-if="dashboard"> <div dash-class ng-if="dashboard">
<dashnav dashboard="dashboard"></dashnav> <dashnav dashboard="dashboard"></dashnav>
<div class="dashboard-container scroll-canvas"> <div class="scroll-canvas scroll-canvas--dashboard">
<div dash-editor-view class="dash-edit-view"></div> <div gemini-scrollbar>
<div class="clearfix"></div> <div class="dashboard-container">
<div dash-editor-view class="dash-edit-view"></div>
<div class="clearfix"></div>
<dashboard-submenu ng-if="dashboard.meta.submenuEnabled" dashboard="dashboard"></dashboard-submenu> <dashboard-submenu ng-if="dashboard.meta.submenuEnabled" dashboard="dashboard"></dashboard-submenu>
<div class="clearfix"></div> <div class="clearfix"></div>
<dash-row class="dash-row" ng-repeat="row in dashboard.rows" row="row" dashboard="dashboard"> <dash-row class="dash-row" ng-repeat="row in dashboard.rows" row="row" dashboard="dashboard">
</dash-row> </dash-row>
<div ng-show='dashboard.meta.canEdit && !dashboard.meta.fullscreen' class="add-row-panel-hint"> <div ng-show='dashboard.meta.canEdit && !dashboard.meta.fullscreen' class="add-row-panel-hint">
<div class="span12" style="text-align:left;"> <div class="span12" style="text-align:left;">
<span style="margin-left: 12px;" ng-click="addRowDefault()" class="pointer btn btn-inverse btn-small"> <span style="margin-left: 12px;" ng-click="addRowDefault()" class="pointer btn btn-inverse btn-small">
<span><i class="fa fa-plus"></i> ADD ROW</span> <span><i class="fa fa-plus"></i> ADD ROW</span>
</span> </span>
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
</div> </div>
<div class="container"> <div class="login-container container">
<div class="signup-page-background"> <div class="signup-page-background">
</div> </div>
......
...@@ -48,6 +48,10 @@ a.text-success:hover, ...@@ -48,6 +48,10 @@ a.text-success:hover,
a.text-success:focus { color: darken($successText, 10%); } a.text-success:focus { color: darken($successText, 10%); }
a { cursor: pointer; } a { cursor: pointer; }
a:focus {
outline:0 none !important;
}
a[disabled] { a[disabled] {
cursor: default; cursor: default;
pointer-events: none !important; pointer-events: none !important;
......
...@@ -37,6 +37,13 @@ ...@@ -37,6 +37,13 @@
bottom: 2px; bottom: 2px;
z-index: 1; z-index: 1;
border-radius: 3px; border-radius: 3px;
&:hover {
.thumb {
opacity: 1;
transition: opacity 100ms ease-in-out;
}
}
} }
.gm-scrollbar.-vertical { .gm-scrollbar.-vertical {
...@@ -56,13 +63,21 @@ ...@@ -56,13 +63,21 @@
height: 0; height: 0;
cursor: pointer; cursor: pointer;
border-radius: inherit; border-radius: inherit;
background-color: lighten($body-bg, 10%); background-color: $dark-5;
transform: translate3d(0,0,0); transform: translate3d(0,0,0);
opacity: 0;
}
.gemini-scrolling {
.gm-scrollbar .thumb {
opacity: 1;
transition: opacity 100ms ease-in-out;
}
} }
.gm-scrollbar .thumb:hover, .gm-scrollbar .thumb:hover,
.gm-scrollbar .thumb:active { .gm-scrollbar .thumb:active {
background-color: lighten($body-bg, 20%); background-color: $blue;
} }
.gm-scrollbar.-vertical .thumb { .gm-scrollbar.-vertical .thumb {
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
max-width: 1100px; max-width: 1100px;
visibility: none; visibility: none;
opacity: 0; opacity: 0;
background: $panel-bg;
height: 65%; height: 65%;
&--fade-in { &--fade-in {
...@@ -76,11 +77,9 @@ ...@@ -76,11 +77,9 @@
.search-results-container { .search-results-container {
height: 100%; height: 100%;
overflow: auto;
display: block; display: block;
line-height: 28px; line-height: 28px;
padding: $spacer; padding: $spacer;
background: $panel-bg;
flex-grow: 10; flex-grow: 10;
.selected { .selected {
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
.main-view { .main-view {
position: relative; position: relative;
flex-grow: 1; flex-grow: 1;
// background: linear-gradient(180deg, #251f1f 0, #17181b);
$gradient-opacity: 0.03; $gradient-opacity: 0.03;
background: linear-gradient(135deg, rgba(26, 42, 108, $gradient-opacity), rgba(178, 31, 31, $gradient-opacity), rgba(253, 187, 45, $gradient-opacity)); //Matt experiement background: linear-gradient(135deg, rgba(26, 42, 108, $gradient-opacity), rgba(178, 31, 31, $gradient-opacity), rgba(253, 187, 45, $gradient-opacity)); //Matt experiement
...@@ -28,7 +27,7 @@ ...@@ -28,7 +27,7 @@
overflow: auto; overflow: auto;
height: 100%; height: 100%;
&.dashboard-container { &--dashboard {
height: calc(100% - 54px); height: calc(100% - 54px);
} }
} }
......
...@@ -1601,9 +1601,10 @@ gaze@^1.0.0, gaze@^1.1.2: ...@@ -1601,9 +1601,10 @@ gaze@^1.0.0, gaze@^1.1.2:
dependencies: dependencies:
globule "^1.0.0" globule "^1.0.0"
gemini-scrollbar@^1.5.2: gemini-scrollbar@^1.5.2, "gemini-scrollbar@https://github.com/grafana/gemini-scrollbar#grafana":
version "1.5.2" version "1.5.2"
resolved "https://registry.yarnpkg.com/gemini-scrollbar/-/gemini-scrollbar-1.5.2.tgz#06528e49afe155c45ce9f7c9ee754a9e6f4ed341" uid "98d8a696502c6226b21358b916e8bf3f8773ad2d"
resolved "https://github.com/grafana/gemini-scrollbar#98d8a696502c6226b21358b916e8bf3f8773ad2d"
generate-function@^2.0.0: generate-function@^2.0.0:
version "2.0.0" version "2.0.0"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment