Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add checks catalog view #241

Merged
merged 8 commits into from
Mar 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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