Initial Commit
This commit is contained in:
511
cmd/ui/css/styles.css
Normal file
511
cmd/ui/css/styles.css
Normal file
@@ -0,0 +1,511 @@
|
||||
:root {
|
||||
--base_length: 35px;
|
||||
--base_margin: 15px;
|
||||
--radius_large: 12px;
|
||||
--shadow: 0px 3px 5px #0003;
|
||||
|
||||
--accent: #78aeed;
|
||||
|
||||
--blue-1: #99c1f1;
|
||||
--blue-2: #62a0ea;
|
||||
--blue-3: #3584e4;
|
||||
--blue-4: #1c71d8;
|
||||
--blue-5: #1a5fb4;
|
||||
|
||||
--green-3: #33d17a;
|
||||
--green-4: #2ec27e;
|
||||
--green-5: #26a269;
|
||||
|
||||
--yellow-4: #f5c211;
|
||||
--yellow-5: #e5a50a;
|
||||
|
||||
--default-margin: 8px var(--base_margin) 8px var(--base_margin);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--success: var(--green-4);
|
||||
--warning: var(--yellow-5);
|
||||
--border: #ffffff17;
|
||||
|
||||
--brightness-mixin: #fff;
|
||||
--brightness-hover: 110%;
|
||||
--brightness-active: 130%;
|
||||
|
||||
--background: #242424;
|
||||
--on_background: #fff;
|
||||
|
||||
--card: #363636;
|
||||
--on_card: #fff;
|
||||
|
||||
--osd: #000;
|
||||
--on_osd: #fff;
|
||||
|
||||
--raised: #4a4a4a;
|
||||
--on_raised: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--success: var(--green-5);
|
||||
--warning: var(--yellow-4);
|
||||
|
||||
--border: #0000001f;
|
||||
|
||||
--brightness-mixin: #000;
|
||||
--brightness-hover: 90%;
|
||||
--brightness-active: 70%;
|
||||
|
||||
--background: #fafafa;
|
||||
--on_background: #323232;
|
||||
|
||||
--card: #fff;
|
||||
--on_card: #333333;
|
||||
|
||||
--osd: #4c4c4c;
|
||||
--on_osd: #fff;
|
||||
|
||||
--raised: #ebebeb;
|
||||
--on_raised: #2f2f2f;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
font-family:
|
||||
system-ui,
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
"Segoe UI",
|
||||
Roboto,
|
||||
Oxygen,
|
||||
Ubuntu,
|
||||
Cantarell,
|
||||
"Open Sans",
|
||||
"Helvetica Neue",
|
||||
sans-serif;
|
||||
background-color: var(--background);
|
||||
color: var(--on_background);
|
||||
}
|
||||
|
||||
.min-w2 {
|
||||
min-width: calc(2 * var(--base_length));
|
||||
}
|
||||
|
||||
.min-w3 {
|
||||
min-width: calc(3 * var(--base_length));
|
||||
}
|
||||
|
||||
.min-w5 {
|
||||
min-width: calc(5 * var(--base_length));
|
||||
}
|
||||
|
||||
.min-w6 {
|
||||
min-width: calc(6 * var(--base_length));
|
||||
}
|
||||
|
||||
.min-w8 {
|
||||
min-width: calc(8 * var(--base_length));
|
||||
}
|
||||
|
||||
.min-w10 {
|
||||
min-width: calc(10 * var(--base_length));
|
||||
}
|
||||
|
||||
.min-w12 {
|
||||
min-width: calc(12 * var(--base_length));
|
||||
}
|
||||
|
||||
.min-w14 {
|
||||
min-width: calc(14 * var(--base_length));
|
||||
}
|
||||
|
||||
.max-w1 {
|
||||
max-width: calc(1 * var(--base_length));
|
||||
}
|
||||
|
||||
.max-w2 {
|
||||
max-width: calc(2 * var(--base_length));
|
||||
}
|
||||
|
||||
.max-w3 {
|
||||
max-width: calc(3 * var(--base_length));
|
||||
}
|
||||
|
||||
.max-w6 {
|
||||
max-width: calc(6 * var(--base_length));
|
||||
}
|
||||
|
||||
.max-w8 {
|
||||
max-width: calc(8 * var(--base_length));
|
||||
}
|
||||
|
||||
.max-w10 {
|
||||
max-width: calc(10 * var(--base_length));
|
||||
}
|
||||
|
||||
.max-w16 {
|
||||
max-width: calc(16 * var(--base_length));
|
||||
}
|
||||
|
||||
.max-w21 {
|
||||
max-width: calc(20 * var(--base_length));
|
||||
}
|
||||
|
||||
.max-w24 {
|
||||
max-width: calc(24 * var(--base_length));
|
||||
}
|
||||
|
||||
.boxed-list {
|
||||
background-color: var(--card);
|
||||
color: var(--on_card);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
border-radius: var(--radius_large);
|
||||
min-width: fit-content !important;
|
||||
border: 1px;
|
||||
border-color: var(--border);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.boxed-list > * {
|
||||
width: 100%;
|
||||
display: inline;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.boxed-list > * > * {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.boxed-list > * > .title {
|
||||
padding-right: 15px;
|
||||
margin-left: 15px;
|
||||
margin-right: auto;
|
||||
color: var(--on_card);
|
||||
}
|
||||
|
||||
.boxed-list > * > .title > * {
|
||||
color: color-mix(in srgb, var(--on_card) 50%, var(--card) 50%);
|
||||
}
|
||||
|
||||
.boxed-list > * > .prefix {
|
||||
margin: 0px 0px 0px var(--base_margin);
|
||||
}
|
||||
|
||||
.boxed-list > * > .suffix {
|
||||
margin: 0px var(--base_margin) 0px var(--base_margin);
|
||||
}
|
||||
|
||||
.boxed-list > *:not(:last-child):not(.expander),
|
||||
.boxed-list > .expander:has(> .expander-state:checked),
|
||||
.boxed-list
|
||||
> .expander:not(:has(> .expander-state:checked)):has(
|
||||
+ .expander-content:not(:last-child)
|
||||
) {
|
||||
border-bottom-right-radius: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
border-style: solid;
|
||||
border-width: 0px 0px 1px 0px;
|
||||
border-color: var(--border);
|
||||
}
|
||||
|
||||
.boxed-list > *:not(:first-child) {
|
||||
border-top-right-radius: 0px;
|
||||
border-top-left-radius: 0px;
|
||||
}
|
||||
|
||||
.boxed-list > *:focus {
|
||||
z-index: 1;
|
||||
outline: solid blue 2px;
|
||||
}
|
||||
|
||||
.boxed-list > * {
|
||||
height: 55px;
|
||||
display: inline-flex;
|
||||
vertical-align: middle;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
transition: background-color 0.15s;
|
||||
}
|
||||
|
||||
.boxed-list > .active:hover {
|
||||
background-color: color-mix(
|
||||
in srgb,
|
||||
var(--card) 98%,
|
||||
var(--brightness-mixin) 2%
|
||||
);
|
||||
}
|
||||
|
||||
.boxed-list > .active:active {
|
||||
background-color: color-mix(
|
||||
in srgb,
|
||||
var(--card) 95%,
|
||||
var(--brightness-mixin) 5%
|
||||
);
|
||||
}
|
||||
|
||||
.boxed-list > * > .prefix {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.round {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.pill {
|
||||
border-radius: 1000px;
|
||||
}
|
||||
|
||||
.raised {
|
||||
background-color: var(--raised);
|
||||
color: var(--on_raised);
|
||||
}
|
||||
|
||||
.flat {
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.suggested-action {
|
||||
background-color: var(--blue-3);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.success {
|
||||
background-color: color-mix(in srgb, currentColor 15%, transparent);
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
.warning {
|
||||
background-color: color-mix(in srgb, currentColor 15%, transparent);
|
||||
color: var(--warning);
|
||||
}
|
||||
|
||||
input {
|
||||
border: none;
|
||||
}
|
||||
|
||||
button {
|
||||
height: var(--base_length);
|
||||
width: inherit;
|
||||
border: none;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
filter 0.15s,
|
||||
outline-offset 0.1s ease-in-out,
|
||||
outline-color 0.1s ease-in-out;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
filter: brightness(var(--brightness-hover));
|
||||
}
|
||||
|
||||
button:active {
|
||||
filter: brightness(var(--brightness-active));
|
||||
}
|
||||
|
||||
* {
|
||||
outline-offset: 1px;
|
||||
outline-style: solid;
|
||||
outline-width: 2px;
|
||||
outline-color: transparent;
|
||||
transition:
|
||||
outline-offset 0.1s ease-in-out,
|
||||
outline-color 0.1s ease-in-out;
|
||||
}
|
||||
|
||||
*:focus-visible {
|
||||
outline-offset: -1px;
|
||||
outline-color: color-mix(in srgb, var(--accent) 50%, transparent);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.adw-radio input[type="radio"] {
|
||||
appearance: none;
|
||||
height: calc(var(--base_length) * 0.6);
|
||||
width: calc(var(--base_length) * 0.6);
|
||||
border-radius: 50%;
|
||||
border: 2px var(--raised) solid;
|
||||
transition: box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.adw-radio input[type="radio"]:checked {
|
||||
border: 2px var(--blue-3) solid;
|
||||
background-color: var(--blue-3);
|
||||
}
|
||||
|
||||
.adw-radio input[type="radio"]:before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 60%;
|
||||
height: 60%;
|
||||
margin: 20% auto;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.adw-radio input[type="radio"]:checked:before {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.card {
|
||||
overflow: hidden;
|
||||
margin: var(--base_margin);
|
||||
border-radius: var(--radius_large);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--on_card);
|
||||
background-color: var(--card);
|
||||
box-shadow: var(--shadow);
|
||||
margin: var(--base_length);
|
||||
}
|
||||
|
||||
.navigation {
|
||||
min-width: fit-content;
|
||||
max-height: calc(var(--base_length) * 1.5);
|
||||
width: 80%;
|
||||
border: 1px solid var(--border);
|
||||
box-shadow: var(--shadow);
|
||||
background-color: var(--background);
|
||||
color: var(--on_background);
|
||||
border-radius: var(--radius_large);
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.navigation > * {
|
||||
margin: 10px;
|
||||
max-height: 32px;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.tag {
|
||||
height: var(--base_length);
|
||||
text-align: center;
|
||||
align-content: center;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.label {
|
||||
margin: var(--default-margin);
|
||||
font-size: var(--base_margin);
|
||||
}
|
||||
|
||||
.heading {
|
||||
font-weight: bold;
|
||||
font-size: var(--base_margin);
|
||||
}
|
||||
|
||||
.title-1 {
|
||||
font-size: x-large;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.expander-state {
|
||||
position: relative;
|
||||
width: 0%;
|
||||
height: 0%;
|
||||
margin: 0%;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.boxed-list > .expander {
|
||||
border-bottom-color: transparent !important;
|
||||
transition: border-bottom 0.15s steps(1, end);
|
||||
}
|
||||
|
||||
.expander:has(> .expander-state:checked) {
|
||||
border-bottom: 1px solid var(--border) !important;
|
||||
transition: border-bottom 0.15s steps(1, start);
|
||||
}
|
||||
|
||||
.expander-content {
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
max-height: 0;
|
||||
transition: max-height 0.15s ease-in-out;
|
||||
box-sizing: border-box;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
.expander:has(> .expander-state:checked) + .expander-content {
|
||||
max-height: 500px;
|
||||
}
|
||||
|
||||
.container-center {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: var(--default-margin);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
th {
|
||||
color: color-mix(in srgb, var(--on_card) 50%, var(--card) 50%);
|
||||
font-size: var(--base_margin);
|
||||
}
|
||||
|
||||
.table-field-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.table-field-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.monospaced {
|
||||
font-family: monospace;
|
||||
font-size: var(--base_margin);
|
||||
}
|
||||
|
||||
.sans-serif {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.placeholder-image {
|
||||
color: color-mix(in srgb, currentColor 60%, transparent);
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
mask-position: center;
|
||||
background-color: currentColor;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 100%;
|
||||
margin: var(--base_margin);
|
||||
}
|
||||
|
||||
.placeholder-image.loupe {
|
||||
mask-image: url("/ui/svg/loupe.svg");
|
||||
}
|
||||
|
||||
.linked-horizontal > *:not(:first-child) {
|
||||
margin-left: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
border-top-left-radius: 0px;
|
||||
}
|
||||
.linked-horizontal > *:not(:last-child) {
|
||||
margin-right: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
border-top-right-radius: 0px;
|
||||
}
|
||||
|
||||
input {
|
||||
color: var(--on_background);
|
||||
background-color: color-mix(in srgb, currentColor 10%, transparent);
|
||||
min-height: var(--base_length);
|
||||
padding-left: var(--base_margin);
|
||||
margin: var(--default-margin);
|
||||
font-size: 15px;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
button {
|
||||
margin: var(--default-margin);
|
||||
position: relative;
|
||||
}
|
||||
38
cmd/ui/html/main.html
Normal file
38
cmd/ui/html/main.html
Normal file
@@ -0,0 +1,38 @@
|
||||
{{block "main" .}}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/ui/css/styles.css" />
|
||||
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
|
||||
<title>SAP CDS-View Search</title>
|
||||
</head>
|
||||
<body>
|
||||
{{template "search-bar" .}}
|
||||
<div id="search-results" class="container-center">
|
||||
{{template "search-placeholder-info" . }}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
{{end}} {{block "search-bar" .}}
|
||||
<form class="container-center linked-horizontal" style="margin-bottom: 30px">
|
||||
<input
|
||||
class="round min-w4 max-w21"
|
||||
style="flex-grow: 1"
|
||||
placeholder="Search here"
|
||||
id="search-bar"
|
||||
name="q"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
class="round raised suggested-action max-w3"
|
||||
style="flex-grow: 1"
|
||||
hx-get="/search"
|
||||
hx-params="*"
|
||||
hx-include="#search-bar"
|
||||
hx-target="#search-results"
|
||||
hx-swap="innerHTML"
|
||||
>
|
||||
Search
|
||||
</button>
|
||||
</form>
|
||||
{{end}}
|
||||
126
cmd/ui/html/search-result.html
Normal file
126
cmd/ui/html/search-result.html
Normal file
@@ -0,0 +1,126 @@
|
||||
{{block "results" .}}
|
||||
<div>
|
||||
{{template "paging" .}}
|
||||
<div class="boxed-list max-w24">
|
||||
{{range .Views}} {{template "result" .}} {{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{end}} {{block "result" .}}
|
||||
<label class="active expander" for="{{.TechnicalName}}">
|
||||
<input class="expander-state" type="checkbox" id="{{.TechnicalName}}" />
|
||||
<div class="title sans-serif">
|
||||
{{.DisplayName}}
|
||||
<div class="monospaced">{{.TechnicalName}}</div>
|
||||
</div>
|
||||
<div
|
||||
class='tag pill suffix {{if eq .State "RELEASED"}} success {{else}} warning {{end}} min-w3'
|
||||
>
|
||||
{{.StateTitle}}
|
||||
</div>
|
||||
</label>
|
||||
<div class="expander-content">
|
||||
<div class="label heading">Field Properties</div>
|
||||
<div class="container-center">{{template "fields" .Fields}}</div>
|
||||
</div>
|
||||
{{end}} {{block "fields" .}}
|
||||
<table>
|
||||
<tr>
|
||||
<th class="table-field-left">Name</th>
|
||||
<th class="table-field-left">Description</th>
|
||||
<th class="table-field-left">Type</th>
|
||||
<th class="table-field-right">Length</th>
|
||||
</tr>
|
||||
{{range .}} {{template "field" .}} {{end}}
|
||||
</table>
|
||||
{{end}} {{block "field" .}}
|
||||
<tr>
|
||||
<td class="table-field-left monospaced">{{.FieldName}}</td>
|
||||
<td class="table-field-left">{{.DescriptionOut}}</td>
|
||||
<td class="table-field-left">{{.DataTypeTitle}}</td>
|
||||
<td class="table-field-right monospaced">{{.FieldLengthOut}}</td>
|
||||
</tr>
|
||||
{{end}} {{block "search-placeholder-no-result" .}}
|
||||
<div>
|
||||
<div class="container-center">
|
||||
<div class="placeholder-image loupe"></div>
|
||||
</div>
|
||||
<div class="container-center">
|
||||
<div class="label title-1">No Results Found</div>
|
||||
</div>
|
||||
<div class="container-center">
|
||||
<div class="label">Try refining your search term</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}} {{block "search-placeholder-info" .}}
|
||||
<div>
|
||||
<div class="container-center">
|
||||
<div class="placeholder-image loupe"></div>
|
||||
</div>
|
||||
<div class="container-center">
|
||||
<div class="label title-1">Search CDS-Views</div>
|
||||
</div>
|
||||
<div class="container-center">
|
||||
<div class="label">Find CDS-Views from the Business Acceleator Hub</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}} {{block "paging" .}}
|
||||
<div>
|
||||
<form style="float: right">
|
||||
<input name="q" disabled hidden value="{{.SearchTerm}}" />
|
||||
<div class="linked-horizontal">
|
||||
<!--button
|
||||
type="submit"
|
||||
class="raised round"
|
||||
style="margin-top: 9px"
|
||||
hx-get="/search"
|
||||
hx-params="*"
|
||||
hx-include="#search-bar"
|
||||
hx-target="#search-results"
|
||||
hx-swap="innerHTML"
|
||||
{{if
|
||||
eq
|
||||
.CurrentPage
|
||||
0}}
|
||||
disabled
|
||||
{{end}}
|
||||
>
|
||||
←</button
|
||||
--><input
|
||||
class="round max-w2"
|
||||
type="number"
|
||||
name="p"
|
||||
value="{{.CurrentPage}}"
|
||||
min="0"
|
||||
max="{{.MaxPage}}"
|
||||
hx-get="/search"
|
||||
hx-params="*"
|
||||
hx-include="#search-bar"
|
||||
hx-target="#search-results"
|
||||
hx-swap="innerHTML"
|
||||
/><input
|
||||
class="round raised max-w2"
|
||||
value="{{.MaxPage}}"
|
||||
disabled
|
||||
/><!--button
|
||||
type="submit"
|
||||
class="raised round"
|
||||
style="margin-top: 9px"
|
||||
hx-get="/search"
|
||||
hx-params="*"
|
||||
hx-include="#search-bar"
|
||||
hx-target="#search-results"
|
||||
hx-swap="innerHTML"
|
||||
{{if
|
||||
eq
|
||||
.CurrentPage
|
||||
.MaxPage}}
|
||||
disabled
|
||||
{{end}}
|
||||
>
|
||||
→
|
||||
</button-->
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
2
cmd/ui/svg/loupe.svg
Normal file
2
cmd/ui/svg/loupe.svg
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><g fill="#222222"><path d="m 10.875 10.0625 c -0.8125 0.148438 -1.105469 1.160156 -0.5 1.71875 l 3 3 c 0.957031 0.9375 2.363281 -0.5 1.40625 -1.4375 l -3 -3 c -0.234375 -0.238281 -0.574219 -0.347656 -0.90625 -0.28125 z m 0 0"/><path d="m 6.570312 0.0625 c -3.578124 0 -6.4999995 2.921875 -6.4999995 6.5 s 2.9218755 6.5 6.4999995 6.5 c 3.578126 0 6.5 -2.921875 6.5 -6.5 s -2.921874 -6.5 -6.5 -6.5 z m 0 2 c 2.5 0 4.5 2.003906 4.5 4.5 c 0 2.5 -2 4.5 -4.5 4.5 c -2.496093 0 -4.5 -2 -4.5 -4.5 c 0 -2.496094 2.003907 -4.5 4.5 -4.5 z m 0 0"/></g></svg>
|
||||
|
After Width: | Height: | Size: 672 B |
12
cmd/ui/ui.go
Normal file
12
cmd/ui/ui.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package ui
|
||||
|
||||
import "text/template"
|
||||
|
||||
var Template *template.Template
|
||||
|
||||
func Load() {
|
||||
Template = template.Must(template.New("ui").ParseFiles(
|
||||
"./cmd/ui/html/main.html",
|
||||
"./cmd/ui/html/search-result.html",
|
||||
))
|
||||
}
|
||||
Reference in New Issue
Block a user