mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-10-03 21:14:30 +02:00
Update component header, format, streamline SV5 components
This commit is contained in:
@@ -1,10 +1,16 @@
|
||||
<!--
|
||||
@component Displays job metaData, serves links to detail pages
|
||||
@component Displays job metaData, serves links to detail pages
|
||||
|
||||
Properties:
|
||||
- `job Object`: The Job Object (GraphQL.Job)
|
||||
- `jobTags [Number]?`: The jobs tags as IDs, default useful for dynamically updating the tags [Default: job.tags]
|
||||
-->
|
||||
Properties:
|
||||
- `job Object`: The Job Object (GraphQL.Job)
|
||||
- `jobTags [Number]?`: The jobs tags as IDs, default useful for dynamically updating the tags [Default: job.tags]
|
||||
- `showJobSelect Bool?`: Show job selection interface for job comparison [Default: false]
|
||||
- `showTagEdit Bool?`: Show tag editing interface [Default: false]
|
||||
- `username String?`: The current username
|
||||
- `authlevel Number`: The current user authentication level
|
||||
- `roles [String]`: Available roles
|
||||
- `isSelected Bool`: Whether job is selected for comparison [Bindable, Default: false]
|
||||
-->
|
||||
|
||||
<script>
|
||||
import { Badge, Button, Icon, Tooltip } from "@sveltestrap/sveltestrap";
|
||||
@@ -16,12 +22,12 @@
|
||||
let {
|
||||
job,
|
||||
jobTags = job.tags,
|
||||
showTagedit = false,
|
||||
showJobSelect = false,
|
||||
showTagEdit = false,
|
||||
username = null,
|
||||
authlevel= null,
|
||||
authlevel = null,
|
||||
roles = null,
|
||||
isSelected = $bindable(),
|
||||
showSelect = false,
|
||||
isSelected = $bindable(false),
|
||||
} = $props();
|
||||
|
||||
/* State Init */
|
||||
@@ -49,7 +55,6 @@
|
||||
}
|
||||
|
||||
function clipJobId(jid) {
|
||||
|
||||
// Navigator clipboard api needs a secure context (https)
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
navigator.clipboard
|
||||
@@ -82,7 +87,7 @@
|
||||
({job.cluster})
|
||||
</span>
|
||||
<span>
|
||||
{#if showSelect}
|
||||
{#if showJobSelect}
|
||||
<Button id={`${job.cluster}-${job.jobId}-select`} outline={!isSelected} color={isSelected? `success`: `secondary`} size="sm" class="mr-2"
|
||||
onclick={() => {
|
||||
isSelected = !isSelected
|
||||
@@ -193,7 +198,7 @@
|
||||
{/if}
|
||||
</p>
|
||||
|
||||
{#if showTagedit}
|
||||
{#if showTagEdit}
|
||||
<hr class="mt-0 mb-2"/>
|
||||
<p class="mb-1">
|
||||
<TagManagement bind:jobTags {job} {username} {authlevel} {roles} renderModal/> :
|
||||
|
@@ -1,14 +1,17 @@
|
||||
<!--
|
||||
@component Data row for a single job displaying metric plots
|
||||
@component Data row for a single job displaying metric plots
|
||||
|
||||
Properties:
|
||||
- `job Object`: The job object (GraphQL.Job)
|
||||
- `metrics [String]`: Currently selected metrics
|
||||
- `plotWidth Number`: Width of the sub-components
|
||||
- `plotHeight Number?`: Height of the sub-components [Default: 275]
|
||||
- `showFootprint Bool`: Display of footprint component for job
|
||||
- `triggerMetricRefresh Bool?`: If changed to true from upstream, will trigger metric query
|
||||
-->
|
||||
Properties:
|
||||
- `job Object`: The job object (GraphQL.Job)
|
||||
- `metrics [String]`: Currently selected metrics
|
||||
- `plotWidth Number`: Width of the sub-components
|
||||
- `plotHeight Number?`: Height of the sub-components [Default: 275]
|
||||
- `showFootprint Bool`: Display of footprint component for job [Default: false]
|
||||
- `previousSelect Bool`: The latest job select state for job comparison [Default: false]
|
||||
- `triggerMetricRefresh Bool?`: If changed to true from upstream, will trigger metric query [Default: false]
|
||||
- `selectJob Func`: The callback function to select a job for comparison
|
||||
- `unselectJob Func`: The callback function to unselect a job from comparison
|
||||
-->
|
||||
|
||||
<script>
|
||||
import { queryStore, gql, getContextClient } from "@urql/svelte";
|
||||
@@ -21,15 +24,15 @@
|
||||
|
||||
/* Svelte 5 Props */
|
||||
let {
|
||||
triggerMetricRefresh = false,
|
||||
job,
|
||||
metrics,
|
||||
plotWidth,
|
||||
plotHeight = 275,
|
||||
showFootprint,
|
||||
showFootprint = false,
|
||||
previousSelect = false,
|
||||
triggerMetricRefresh = false,
|
||||
selectJob,
|
||||
unselectJob
|
||||
unselectJob,
|
||||
} = $props();
|
||||
|
||||
/* Const Init */
|
||||
|
@@ -1,240 +1,239 @@
|
||||
<!--
|
||||
@component Pagination selection component
|
||||
@component Pagination selection component
|
||||
|
||||
Properties:
|
||||
- page: Number (changes from inside)
|
||||
- itemsPerPage: Number (changes from inside)
|
||||
- totalItems: Number (only displayed)
|
||||
|
||||
Events:
|
||||
- "update-paging": { page: Number, itemsPerPage: Number }
|
||||
- Dispatched once immediately and then each time page or itemsPerPage changes
|
||||
-->
|
||||
Properties:
|
||||
- `page Number?`: Current page [Default: 1]
|
||||
- `itemsPerPage Number?`: Current items displayed per page [Default: 10]
|
||||
- `totalItems Number?`: Total count of items [Default: 0]
|
||||
- `itemText String?`: Name of paged items, e.g. "Jobs" [Default: "items"]
|
||||
- `pageSizes [Number!]?`: Options available for page sizes [Default: [10, 25, 50]]
|
||||
- `updatePaging Func`: The callback function to apply current paging selection
|
||||
-->
|
||||
|
||||
<script>
|
||||
/* Svelte 5 Props */
|
||||
let {
|
||||
page = 1,
|
||||
itemsPerPage = 10,
|
||||
totalItems = 0,
|
||||
itemText = "items",
|
||||
pageSizes = [10,25,50],
|
||||
updatePaging
|
||||
} = $props();
|
||||
/* Svelte 5 Props */
|
||||
let {
|
||||
page = 1,
|
||||
itemsPerPage = 10,
|
||||
totalItems = 0,
|
||||
itemText = "items",
|
||||
pageSizes = [10, 25, 50],
|
||||
updatePaging
|
||||
} = $props();
|
||||
|
||||
/* Derived */
|
||||
const backButtonDisabled = $derived((page === 1));
|
||||
const nextButtonDisabled = $derived((page >= (totalItems / itemsPerPage)));
|
||||
/* Derived */
|
||||
const backButtonDisabled = $derived((page === 1));
|
||||
const nextButtonDisabled = $derived((page >= (totalItems / itemsPerPage)));
|
||||
|
||||
/* Functions */
|
||||
function pageUp ( event ) {
|
||||
event.preventDefault();
|
||||
page += 1;
|
||||
updatePaging({ itemsPerPage, page });
|
||||
}
|
||||
|
||||
function pageBack ( event ) {
|
||||
event.preventDefault();
|
||||
page -= 1;
|
||||
updatePaging({ itemsPerPage, page });
|
||||
}
|
||||
/* Functions */
|
||||
function pageUp ( event ) {
|
||||
event.preventDefault();
|
||||
page += 1;
|
||||
updatePaging({ itemsPerPage, page });
|
||||
}
|
||||
|
||||
function pageBack ( event ) {
|
||||
event.preventDefault();
|
||||
page -= 1;
|
||||
updatePaging({ itemsPerPage, page });
|
||||
}
|
||||
|
||||
function pageReset ( event ) {
|
||||
event.preventDefault();
|
||||
page = 1;
|
||||
updatePaging({ itemsPerPage, page });
|
||||
}
|
||||
function pageReset ( event ) {
|
||||
event.preventDefault();
|
||||
page = 1;
|
||||
updatePaging({ itemsPerPage, page });
|
||||
}
|
||||
|
||||
function updateItems ( event ) {
|
||||
event.preventDefault();
|
||||
updatePaging({ itemsPerPage, page });
|
||||
}
|
||||
function updateItems ( event ) {
|
||||
event.preventDefault();
|
||||
updatePaging({ itemsPerPage, page });
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="cc-pagination" >
|
||||
<div class="cc-pagination-left">
|
||||
<label for="cc-pagination-select">{ itemText } per page:</label>
|
||||
<div class="cc-pagination-select-wrapper">
|
||||
<select onblur={(e) => pageReset(e)} onchange={(e) => updateItems(e)} bind:value={itemsPerPage} id="cc-pagination-select" class="cc-pagination-select">
|
||||
{#each pageSizes as size}
|
||||
<option value="{size}">{size}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<span class="focus"></span>
|
||||
</div>
|
||||
<span class="cc-pagination-text">
|
||||
{ ((page - 1) * itemsPerPage) + 1 } - { Math.min((page - 1) * itemsPerPage + itemsPerPage, totalItems) } of { totalItems } { itemText }
|
||||
</span>
|
||||
</div>
|
||||
<div class="cc-pagination-right">
|
||||
{#if !backButtonDisabled}
|
||||
<button aria-label="page-reset" class="reset nav" type="button"
|
||||
onclick={(e) => pageReset(e)}></button>
|
||||
<button aria-label="page-back" class="left nav" type="button"
|
||||
onclick={(e) => pageBack(e)}></button>
|
||||
{/if}
|
||||
{#if !nextButtonDisabled}
|
||||
<button aria-label="page-up" class="right nav" type="button"
|
||||
onclick={(e) => pageUp(e)}></button>
|
||||
{/if}
|
||||
<div class="cc-pagination-left">
|
||||
<label for="cc-pagination-select">{ itemText } per page:</label>
|
||||
<div class="cc-pagination-select-wrapper">
|
||||
<select onblur={(e) => pageReset(e)} onchange={(e) => updateItems(e)} bind:value={itemsPerPage} id="cc-pagination-select" class="cc-pagination-select">
|
||||
{#each pageSizes as size}
|
||||
<option value="{size}">{size}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<span class="focus"></span>
|
||||
</div>
|
||||
<span class="cc-pagination-text">
|
||||
{ ((page - 1) * itemsPerPage) + 1 } - { Math.min((page - 1) * itemsPerPage + itemsPerPage, totalItems) } of { totalItems } { itemText }
|
||||
</span>
|
||||
</div>
|
||||
<div class="cc-pagination-right">
|
||||
{#if !backButtonDisabled}
|
||||
<button aria-label="page-reset" class="reset nav" type="button"
|
||||
onclick={(e) => pageReset(e)}></button>
|
||||
<button aria-label="page-back" class="left nav" type="button"
|
||||
onclick={(e) => pageBack(e)}></button>
|
||||
{/if}
|
||||
{#if !nextButtonDisabled}
|
||||
<button aria-label="page-up" class="right nav" type="button"
|
||||
onclick={(e) => pageUp(e)}></button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
*, *::before, *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
*, *::before, *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
vertical-align: baseline;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
vertical-align: baseline;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
label, select, button {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
vertical-align: baseline;
|
||||
color: #525252;
|
||||
}
|
||||
label, select, button {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
vertical-align: baseline;
|
||||
color: #525252;
|
||||
}
|
||||
|
||||
button {
|
||||
position: relative;
|
||||
border: none;
|
||||
border-left: 1px solid #e0e0e0;
|
||||
height: 3rem;
|
||||
width: 3rem;
|
||||
background: 0 0;
|
||||
transition: all 70ms;
|
||||
}
|
||||
button {
|
||||
position: relative;
|
||||
border: none;
|
||||
border-left: 1px solid #e0e0e0;
|
||||
height: 3rem;
|
||||
width: 3rem;
|
||||
background: 0 0;
|
||||
transition: all 70ms;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #dde1e6;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #dde1e6;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
right: -1px;
|
||||
bottom: -1px;
|
||||
border: 1px solid blue;
|
||||
border-radius: inherit;
|
||||
}
|
||||
button:focus {
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
right: -1px;
|
||||
bottom: -1px;
|
||||
border: 1px solid blue;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
.nav::after {
|
||||
content: "";
|
||||
width: 0.9em;
|
||||
height: 0.8em;
|
||||
background-color: #777;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
}
|
||||
.nav::after {
|
||||
content: "";
|
||||
width: 0.9em;
|
||||
height: 0.8em;
|
||||
background-color: #777;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.nav:disabled {
|
||||
background-color: #fff;
|
||||
cursor: no-drop;
|
||||
}
|
||||
.nav:disabled {
|
||||
background-color: #fff;
|
||||
cursor: no-drop;
|
||||
}
|
||||
|
||||
.reset::after {
|
||||
clip-path: polygon(100% 0%, 75% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
|
||||
margin-top: -0.3em;
|
||||
margin-left: -0.5em;
|
||||
}
|
||||
.reset::after {
|
||||
clip-path: polygon(100% 0%, 75% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
|
||||
margin-top: -0.3em;
|
||||
margin-left: -0.5em;
|
||||
}
|
||||
|
||||
.right::after {
|
||||
clip-path: polygon(100% 50%, 50% 0, 50% 100%);
|
||||
margin-top: -0.3em;
|
||||
margin-left: -0.5em;
|
||||
}
|
||||
.right::after {
|
||||
clip-path: polygon(100% 50%, 50% 0, 50% 100%);
|
||||
margin-top: -0.3em;
|
||||
margin-left: -0.5em;
|
||||
}
|
||||
|
||||
.left::after {
|
||||
clip-path: polygon(50% 0, 0 50%, 50% 100%);
|
||||
margin-top: -0.3em;
|
||||
margin-left: -0.3em;
|
||||
}
|
||||
.left::after {
|
||||
clip-path: polygon(50% 0, 0 50%, 50% 100%);
|
||||
margin-top: -0.3em;
|
||||
margin-left: -0.3em;
|
||||
}
|
||||
|
||||
.cc-pagination-select-wrapper::after {
|
||||
content: "";
|
||||
width: 0.8em;
|
||||
height: 0.5em;
|
||||
background-color: #777;
|
||||
clip-path: polygon(100% 0%, 0 0%, 50% 100%);
|
||||
justify-self: end;
|
||||
}
|
||||
.cc-pagination-select-wrapper::after {
|
||||
content: "";
|
||||
width: 0.8em;
|
||||
height: 0.5em;
|
||||
background-color: #777;
|
||||
clip-path: polygon(100% 0%, 0 0%, 50% 100%);
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.cc-pagination {
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
}
|
||||
.cc-pagination {
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.cc-pagination-text {
|
||||
color: #525252;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
.cc-pagination-text {
|
||||
color: #525252;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.cc-pagination-text {
|
||||
color: #525252;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
.cc-pagination-text {
|
||||
color: #525252;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.cc-pagination-left {
|
||||
padding: 0 1rem;
|
||||
height: 3rem;
|
||||
}
|
||||
.cc-pagination-left {
|
||||
padding: 0 1rem;
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
.cc-pagination-select-wrapper {
|
||||
display: grid;
|
||||
grid-template-areas: "select";
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding: 0 0.5em;
|
||||
min-width: 3em;
|
||||
max-width: 6em;
|
||||
border-right: 1px solid #e0e0e0;
|
||||
cursor: pointer;
|
||||
transition: all 70ms;
|
||||
}
|
||||
.cc-pagination-select-wrapper {
|
||||
display: grid;
|
||||
grid-template-areas: "select";
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding: 0 0.5em;
|
||||
min-width: 3em;
|
||||
max-width: 6em;
|
||||
border-right: 1px solid #e0e0e0;
|
||||
cursor: pointer;
|
||||
transition: all 70ms;
|
||||
}
|
||||
|
||||
.cc-pagination-select-wrapper:hover {
|
||||
background-color: #dde1e6;
|
||||
}
|
||||
.cc-pagination-select-wrapper:hover {
|
||||
background-color: #dde1e6;
|
||||
}
|
||||
|
||||
select,
|
||||
.cc-pagination-select-wrapper::after {
|
||||
grid-area: select;
|
||||
}
|
||||
select,
|
||||
.cc-pagination-select-wrapper::after {
|
||||
grid-area: select;
|
||||
}
|
||||
|
||||
.cc-pagination-select {
|
||||
height: 3rem;
|
||||
appearance: none;
|
||||
background-color: transparent;
|
||||
padding: 0 1em 0 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
width: 100%;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
cursor: inherit;
|
||||
line-height: inherit;
|
||||
z-index: 1;
|
||||
outline: none;
|
||||
}
|
||||
.cc-pagination-select {
|
||||
height: 3rem;
|
||||
appearance: none;
|
||||
background-color: transparent;
|
||||
padding: 0 1em 0 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
width: 100%;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
cursor: inherit;
|
||||
line-height: inherit;
|
||||
z-index: 1;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
select:focus + .focus {
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
right: -1px;
|
||||
bottom: -1px;
|
||||
border: 1px solid blue;
|
||||
border-radius: inherit;
|
||||
}
|
||||
select:focus + .focus {
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
right: -1px;
|
||||
bottom: -1px;
|
||||
border: 1px solid blue;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
.cc-pagination-right {
|
||||
height: 3rem;
|
||||
}
|
||||
.cc-pagination-right {
|
||||
height: 3rem;
|
||||
}
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user