Introduced ActionButton component as a replacement for HTML's button.

This commit is contained in:
baldo 2022-08-02 16:31:38 +02:00
parent d159e22c50
commit 215f70db26
8 changed files with 146 additions and 69 deletions

View file

@ -41,34 +41,4 @@ a {
outline: 0.1em solid $link-hover-color;
}
}
button {
padding: $button-padding;
border-radius: $button-border-radius;
border-width: $button-border-width;
border-style: $button-border-style;
cursor: pointer;
@each $variant, $color in $variant-colors {
&.#{$variant} {
background-color: map-get($variant-text-colors, $variant);
border-color: $color;
color: $color;
&:hover, &:active {
background-color: $color;
border-color: $color;
color: map-get($variant-text-colors, $variant);
}
&:focus {
background-color: $color;
border-color: $page-background-color;
color: map-get($variant-text-colors, $variant);
outline: 0.1em solid $color;
}
}
}
}
</style>

View file

@ -1,11 +1,11 @@
<script setup lang="ts">
import {computed, defineProps} from "vue";
import type {NodesFilter} from "@/types";
import type {ComponentVariant, NodesFilter} from "@/types";
interface Props {
title: string;
icon: string;
variant: string;
variant: ComponentVariant;
value: number;
link: string;
filter?: NodesFilter;
@ -29,7 +29,7 @@ const linkTarget = computed(() => {
<template>
<RouterLink :to="linkTarget" :class="['statistics-card', 'statistics-card-' + variant]">
<i :class="['fa', 'fa-' + icon]" aria-hidden="true" />
<i :class="['fa', 'fa-' + icon]" aria-hidden="true"/>
<dl>
<dt>{{ title }}</dt>
<dd>{{ value }}</dd>

View file

@ -0,0 +1,70 @@
<script setup lang="ts">
import type {ButtonSize, ComponentVariant} from "@/types";
interface Props {
variant: ComponentVariant;
size: ButtonSize;
icon: string;
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: "click"): void,
}>();
function onClick() {
emit("click");
}
</script>
<template>
<button :class="[size, variant]" @click="onClick">
<i :class="['fa', `fa-${icon}`]" aria-hidden="true"/>
<slot></slot>
</button>
</template>
<style scoped lang="scss">
@import "../../scss/variables";
button {
margin: 0.3em;
padding: $button-padding;
border-radius: $button-border-radius;
border-width: $button-border-width;
border-style: $button-border-style;
cursor: pointer;
font-weight: 600;
@each $variant, $color in $variant-colors {
&.#{$variant} {
background-color: $color;
border-color: $color;
color: map-get($variant-text-colors, $variant);
&:hover, &:active {
background-color: $page-background-color;
border-color: $color;
color: $color;
}
&:focus {
background-color: $color;
border-color: $page-background-color;
color: map-get($variant-text-colors, $variant);
outline: $color solid $button-outline-width;
}
}
}
@each $size, $font-size in $button-sizes {
&.#{$size} {
font-size: $font-size;
}
}
}
</style>

View file

@ -17,11 +17,11 @@ $variant-colors: (
info: #0097c4,
);
$variant-text-colors: (
// primary: do not use, contrast too low
success: $gray-darkest,
warning: $gray-darkest,
danger: $gray-darkest,
info: $gray-darkest,
primary: $black,
success: $black,
warning: $black,
danger: $black,
info: $black,
);
$variant-color-primary: map-get($variant-colors, primary);
@ -48,10 +48,17 @@ $input-border: 0.1em solid $page-background-color;
$input-border-radius: 0.5em;
$input-focus-outline: 0.1em solid $variant-color-info;
$button-margin: 0.3em;
$button-padding: 0.25em 0.5em;
$button-border-radius: $input-border-radius;
$button-border-width: 0.1em;
$button-border-width: 0.15em;
$button-border-style: solid;
$button-outline-width: 0.15em;
$button-sizes: (
small: 0.8em,
medium: 1em,
large: 1.15em,
);
// Navigation
$nav-bar-background-color: $gray-dark;

View file

@ -1 +1,15 @@
export * from "./shared";
export enum ButtonSize {
SMALL = "small",
MEDIUM = "medium",
LARGE = "large",
}
export enum ComponentVariant {
PRIMARY = "primary",
SUCCESS = "success",
WARNING = "warning",
DANGER = "danger",
INFO = "info",
}

View file

@ -1,7 +1,7 @@
<script setup lang="ts">
import StatisticsCard from "@/components/admin/StatisticsCard.vue";
import {useStatisticsStore} from "@/stores/statistics";
import {MonitoringState} from "@/types";
import {ComponentVariant, MonitoringState} from "@/types";
const statistics = useStatisticsStore();
@ -20,14 +20,14 @@ refresh();
<StatisticsCard
title="Registrierte Knoten"
icon="circle-o"
variant="info"
:variant="ComponentVariant.INFO"
:value="statistics.getStatistics.nodes.registered"
link="/admin/nodes"
/>
<StatisticsCard
title="Mit hinterlegtem fastd-Key"
icon="lock"
variant="warning"
:variant="ComponentVariant.WARNING"
:value="statistics.getStatistics.nodes.withVPN"
link="/admin/nodes"
:filter="{hasKey: true}"
@ -35,7 +35,7 @@ refresh();
<StatisticsCard
title="Mit Koordinaten"
icon="map-marker"
variant="success"
:variant="ComponentVariant.SUCCESS"
:value="statistics.getStatistics.nodes.withCoords"
link="/admin/nodes"
:filter="{hasCoords: true}"
@ -43,7 +43,7 @@ refresh();
<StatisticsCard
title="Monitoring aktiv"
icon="heartbeat"
variant="success"
:variant="ComponentVariant.SUCCESS"
:value="statistics.getStatistics.nodes.monitoring.active"
link="/admin/nodes"
:filter="{monitoringState: MonitoringState.ACTIVE}"
@ -51,7 +51,7 @@ refresh();
<StatisticsCard
title="Monitoring noch nicht bestätigt"
icon="envelope"
variant="danger"
:variant="ComponentVariant.DANGER"
:value="statistics.getStatistics.nodes.monitoring.pending"
link="/admin/nodes"
:filter="{monitoringState: MonitoringState.PENDING}"

View file

@ -2,28 +2,14 @@
import {useNodesStore} from "@/stores/nodes";
import {onMounted, type PropType, ref, watch} from "vue";
import type {DomainSpecificNodeResponse, MAC, NodesFilter, SearchTerm} from "@/types";
import {NodeSortField, SortDirection} from "@/types";
import {ButtonSize, ComponentVariant, NodeSortField, SortDirection} from "@/types";
import Pager from "@/components/Pager.vue";
import ActionButton from "@/components/form/ActionButton.vue";
import LoadingContainer from "@/components/LoadingContainer.vue";
import NodesFilterPanel from "@/components/nodes/NodesFilterPanel.vue";
import {SortTH} from "@/components/table/SortTH.vue";
import router from "@/router";
function debug(...args: any[]): void {
console.debug("==================================================================");
console.debug("AdminNodesVue:", ...args);
console.table({
filter: JSON.stringify(props.filter),
searchTerm: props.searchTerm,
sortDirection: props.sortDirection,
sortField: props.sortField,
});
console.debug("==================================================================");
console.debug();
}
debug("init page");
const NODE_PER_PAGE = 50;
// noinspection JSUnusedGlobalSymbols
@ -145,18 +131,22 @@ watch(props, async () => {
@changePage="refresh"/>
<div class="actions">
<button
<ActionButton
v-if="redactFieldsByDefault"
class="warning"
:variant="ComponentVariant.WARNING"
:size="ButtonSize.SMALL"
icon="eye"
@click="redactAllFields(false)">
Sensible Daten einblenden
</button>
<button
</ActionButton>
<ActionButton
v-if="!redactFieldsByDefault"
class="success"
:variant="ComponentVariant.SUCCESS"
:size="ButtonSize.SMALL"
icon="eye-slash"
@click="redactAllFields(true)">
Sensible Daten ausblenden
</button>
</ActionButton>
</div>
<LoadingContainer :loading="loading">

View file

@ -1,12 +1,38 @@
<script setup lang="ts">
import ActionButton from "@/components/form/ActionButton.vue";
import {ButtonSize, ComponentVariant} from "@/types";
</script>
<template>
<div>
<h2>Willkommen!</h2>
<p>Du hast einen neuen Freifunk Hamburg Router (Knoten), den Du in Betrieb nehmen möchtest? Du hast schon einen Knoten in Betrieb und möchtest seine Daten ändern? Oder Du möchtest einen Knoten, der nicht mehr in Betrieb ist löschen? Dann bist Du hier richtig!</p>
<p>Du hast einen neuen Freifunk Hamburg Router (Knoten), den Du in Betrieb nehmen möchtest? Du hast schon einen
Knoten in Betrieb und möchtest seine Daten ändern? Oder Du möchtest einen Knoten, der nicht mehr in Betrieb
ist löschen? Dann bist Du hier richtig!</p>
<div class="actions">
<ActionButton
:variant="ComponentVariant.INFO"
:size="ButtonSize.LARGE"
icon="dot-circle-o">
Neuen Knoten anmelden
</ActionButton>
<ActionButton
:variant="ComponentVariant.PRIMARY"
:size="ButtonSize.LARGE"
icon="pencil">
Knotendaten ändern
</ActionButton>
<ActionButton
:variant="ComponentVariant.WARNING"
:size="ButtonSize.LARGE"
icon="trash">
Knoten löschen
</ActionButton>
</div>
</div>
</template>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
</style>