Skip to content

Commit

Permalink
Add checks catalog view (#241)
Browse files Browse the repository at this point in the history
* Copy current checks selection view to the catalog sidebar element

* Add collapsable element to the checks catalog

* Change hardcoded catalog data to include the provider

* Add cloud provider selection in the catalog

* Apply new css styles to markdown blocks

* Fix eslint issues

* Render markdown styles in the check description

* Change setSelected property name to onChange
  • Loading branch information
arbulu89 authored Mar 25, 2022
1 parent cac4e55 commit c3c2ab5
Show file tree
Hide file tree
Showing 10 changed files with 965 additions and 345 deletions.
2 changes: 2 additions & 0 deletions assets/css/app.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* This file is for your main application CSS */
@import './markdown.scss';

@tailwind base;

@tailwind components;
Expand Down
185 changes: 185 additions & 0 deletions assets/css/markdown.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
.markdown {
* {
margin: 0;
padding: 0;
}
body {
font: 13.34px helvetica, arial, freesans, clean, sans-serif;
color: black;
line-height: 1.4em;
background-color: #f8f8f8;
}
p {
margin: 1em 0;
line-height: 1.5em;
}
table {
font-size: inherit;
font: 100%;
margin: 1em;
}
table th {
border-bottom: 1px solid #bbb;
padding: 0.2em 1em;
}
table td {
border-bottom: 1px solid #ddd;
padding: 0.2em 1em;
}
input[type='text'],
input[type='password'],
input[type='image'],
textarea {
font: 99% helvetica, arial, freesans, sans-serif;
}
select,
option {
padding: 0 0.25em;
}
optgroup {
margin-top: 0.5em;
}
pre,
code {
font: 12px Menlo, Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono',
monospace;
}
pre {
margin: 1em 0;
font-size: 12px;
background-color: #eee;
border: 1px solid #ddd;
padding: 5px;
line-height: 1.5em;
color: #444;
overflow: auto;
-webkit-box-shadow: rgba(0, 0, 0, 0.07) 0 1px 2px inset;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
pre code {
padding: 0;
font-size: 12px;
background-color: #eee;
border: none;
}
code {
font-size: 12px;
background-color: #f8f8ff;
color: #444;
padding: 0 0.2em;
border: 1px solid #dedede;
}
img {
border: 0;
max-width: 100%;
}
abbr {
border-bottom: none;
}
a {
color: #4183c4;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a code,
a:link code,
a:visited code {
color: #4183c4;
}
h2,
h3 {
margin: 1em 0;
}
h1,
h2,
h3,
h4,
h5,
h6 {
border: 0;
}
h1 {
font-size: 170%;
border-top: 4px solid #aaa;
padding-top: 0.5em;
margin-top: 1.5em;
}
h1:first-child {
margin-top: 0;
padding-top: 0.25em;
border-top: none;
}
h2 {
font-size: 150%;
margin-top: 0.5em;
border-top: 2px solid #e0e0e0;
padding-top: 0.5em;
}
h3 {
margin-top: 1em;
}
hr {
border: 1px solid #ddd;
}
ul {
margin: 1em 0 1em 2em;
list-style-type: circle;
}
ol {
margin: 1em 0 1em 2em;
list-style-type: decimal;
}
ul li,
ol li {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
ul ul,
ul ol,
ol ol,
ol ul {
margin-top: 0;
margin-bottom: 0;
}
blockquote {
margin: 1em 0;
border-left: 5px solid #ddd;
padding-left: 0.6em;
color: #555;
}
dt {
font-weight: bold;
margin-left: 1em;
}
dd {
margin-left: 2em;
margin-bottom: 1em;
}
sup {
font-size: 0.83em;
vertical-align: super;
line-height: 0;
}
* {
-webkit-print-color-adjust: exact;
}
@media screen and (min-width: 914px) {
body {
width: 854px;
margin: 0 auto;
}
}
@media print {
table,
pre {
page-break-inside: avoid;
}
pre {
word-wrap: break-word;
}
}
}
105 changes: 105 additions & 0 deletions assets/js/components/ChecksCatalog/ChecksCatalog.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import React, { useState, useEffect } from 'react';
import { useSelector } from 'react-redux';

import { Disclosure, Transition } from '@headlessui/react';

import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';

import ProviderSelection from './ProviderSelection';

const ChecksCatalog = () => {
const catalog = useSelector((state) => state.catalog.catalog);
const providers = catalog.map((provider) => provider.provider);
const [selected, setSelected] = useState(providers[0]);

useEffect(() => {
setSelected(providers[0]);
}, [providers[0]]);

return (
<div>
<ProviderSelection
providers={providers}
selected={selected}
onChange={setSelected}
/>
{catalog
.filter((provider) => provider.provider == selected)
.map(({ _, groups }) =>
groups.map(({ group, checks }) => (
<div
key={group.id}
className="bg-white shadow overflow-hidden sm:rounded-md mb-8"
>
<div className="bg-white px-4 py-5 border-b border-gray-200 sm:px-6">
<h3 className="text-lg leading-6 font-medium text-gray-900">
{group}
</h3>
</div>
<ul role="list" className="divide-y divide-gray-200">
{checks.map((check) => (
<li key={check.id}>
<Disclosure>
<Disclosure.Button
as="div"
className="flex justify-between w-full cursor-pointer hover:bg-gray-100"
>
<div className="px-4 py-4 sm:px-6">
<div className="flex items-center">
<p className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
{check.id}
</p>
{check.premium > 0 && (
<p className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
Premium
</p>
)}
</div>
<div className="mt-2 sm:flex sm:justify-between">
<div className="sm:flex">
<p className="flex items-center text-sm">
<ReactMarkdown
className="markdown"
remarkPlugins={[remarkGfm]}
>
{check.description}
</ReactMarkdown>
</p>
</div>
</div>
</div>
</Disclosure.Button>
<Transition
enter="transition duration-100 ease-out"
enterFrom="transform opacity-0"
enterTo="transform opacity-100"
leave="transition duration-100 ease-out"
leaveFrom="transform opacity-100"
leaveTo="transform opacity-0"
>
<Disclosure.Panel className="border-none">
<div className="px-8 py-4 sm:px-8">
<div className="px-4 py-4 sm:px-4 bg-slate-100 rounded">
<ReactMarkdown
className="markdown"
remarkPlugins={[remarkGfm]}
>
{check.remediation}
</ReactMarkdown>
</div>
</div>
</Disclosure.Panel>
</Transition>
</Disclosure>
</li>
))}
</ul>
</div>
))
)}
</div>
);
};

export default ChecksCatalog;
63 changes: 63 additions & 0 deletions assets/js/components/ChecksCatalog/ProviderSelection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { Fragment } from 'react';

import { Listbox, Transition } from '@headlessui/react';
import { CheckIcon, SelectorIcon } from '@heroicons/react/solid';

const ProviderSelection = ({ providers, selected, onChange }) => {
return (
<div className="w-72 pb-4">
<Listbox value={selected} onChange={onChange}>
<div className="relative mt-1">
<Listbox.Button className="relative w-full py-2 pl-3 pr-10 text-left bg-white rounded-lg shadow-md cursor-default focus:outline-none focus-visible:ring-2 focus-visible:ring-opacity-75 focus-visible:ring-white focus-visible:ring-offset-orange-300 focus-visible:ring-offset-2 focus-visible:border-indigo-500 sm:text-sm">
<span className="block truncate">{selected}</span>
<span className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
<SelectorIcon
className="w-5 h-5 text-gray-400"
aria-hidden="true"
/>
</span>
</Listbox.Button>
<Transition
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options className="absolute w-full py-1 mt-1 overflow-auto text-base bg-white rounded-md shadow-lg max-h-60 ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{providers.map((provider, providerIdx) => (
<Listbox.Option
key={providerIdx}
className={({ active }) =>
`cursor-default select-none relative py-2 pl-10 pr-4 ${
active ? 'text-green-900 bg-green-100' : 'text-gray-900'
}`
}
value={provider}
>
{({ selected }) => (
<>
<span
className={`block truncate ${
selected ? 'font-medium' : 'font-normal'
}`}
>
{provider}
</span>
{selected ? (
<span className="absolute inset-y-0 left-0 flex items-center pl-3 text-green-600">
<CheckIcon className="w-5 h-5" aria-hidden="true" />
</span>
) : null}
</>
)}
</Listbox.Option>
))}
</Listbox.Options>
</Transition>
</div>
</Listbox>
</div>
);
};

export default ProviderSelection;
3 changes: 3 additions & 0 deletions assets/js/components/ChecksCatalog/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import ChecksCatalog from './ChecksCatalog';

export default ChecksCatalog;
6 changes: 6 additions & 0 deletions assets/js/components/Layout/Layout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
EOS_INFO,
EOS_SYSTEM_GROUP,
EOS_STORAGE,
EOS_LIST,
} from 'eos-icons-react';

import TrentoLogo from '../../../static/trento-logo-stacked.svg';
Expand Down Expand Up @@ -35,6 +36,11 @@ const navigation = [
href: '/databases',
icon: EOS_STORAGE,
},
{
name: 'Checks catalog',
href: '/catalog',
icon: EOS_LIST,
},
{ name: 'About', href: '/about', icon: EOS_INFO },
];

Expand Down
Loading

0 comments on commit c3c2ab5

Please sign in to comment.