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 Warning indicator. #9160

Merged
merged 10 commits into from
Mar 4, 2024
60 changes: 16 additions & 44 deletions app/gui2/src/assets/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,25 @@
@import url('./font-mplus1.css');
@import url('./font-dejavu.css');

/* color palette from <https://github.com/vuejs/theme> */
:root {
--vt-c-white: #ffffff;
--vt-c-white-soft: #f8f8f8;
--vt-c-white-mute: #f2f2f2;

--vt-c-black: #181818;
--vt-c-black-soft: #222222;
--vt-c-black-mute: #282828;

--vt-c-indigo: #2c3e50;

--vt-c-divider-light-1: rgba(60 60 60 / 0.29);
--vt-c-divider-light-2: rgba(60 60 60 / 0.12);
--vt-c-divider-dark-1: rgba(84 84 84 / 0.65);
--vt-c-divider-dark-2: rgba(84 84 84 / 0.48);

--vt-c-text-light-1: rgba(118 118 118);
--vt-c-text-light-2: rgba(60 60 60 / 0.66);
--vt-c-text-dark-1: var(--vt-c-white);
--vt-c-text-dark-2: rgba(235 235 235 / 0.64);
}

/* semantic color variables for this project */
:root {
--color-background: var(--vt-c-white);
--color-background-soft: var(--vt-c-white-soft);
--color-background-mute: var(--vt-c-white-mute);

--color-border: var(--vt-c-divider-light-2);
--color-border-hover: var(--vt-c-divider-light-1);

--color-heading: var(--vt-c-text-light-1);
--color-text: var(--vt-c-text-light-1);

--color-primary: rgba(0 0 0 / 0.6);
--color-text-light: rgba(255 255 255 / 0.7);
--color-text-inversed: rgba(255 255 255);
--color-app-bg: rgba(255 255 255 / 0.8);
--color-menu-entry-hover-bg: rgba(0 0 0 / 0.1);
--color-text: rgb(118 118 118);
--color-primary: rgb(0 0 0 / 0.6);
--color-text-light: rgb(255 255 255 / 0.7);
--color-text-inversed: rgb(255 255 255);
--color-app-bg: rgb(255 255 255 / 0.8);
--color-menu-entry-hover-bg: rgb(0 0 0 / 0.1);
--color-visualization-bg: rgb(255 242 242);
--color-dim: rgba(0 0 0 / 0.25);
--color-frame-bg: rgba(255 255 255 / 0.3);
--color-frame-selected-bg: rgba(255 255 255 / 0.7);
--color-widget: rgba(255 255 255 / 0.12);
--color-widget-selected: rgba(255 255 255 / 0.58);
--color-port-connected: rgba(255 255 255 / 0.15);
--color-dim: rgb(0 0 0 / 0.25);
--color-frame-bg: rgb(255 255 255 / 0.3);
--color-frame-selected-bg: rgb(255 255 255 / 0.7);
--color-widget: rgb(255 255 255 / 0.12);
--color-widget-selected: rgb(255 255 255 / 0.58);
--color-port-connected: rgb(255 255 255 / 0.15);

/* colors for specific icons */
--color-warning: rgb(251 188 5);
--color-error: rgb(234 67 53);
}

/* non-color variables */
Expand Down
32 changes: 28 additions & 4 deletions app/gui2/src/components/GraphEditor/GraphNode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import GraphNodeComment from '@/components/GraphEditor/GraphNodeComment.vue'
import GraphNodeError from '@/components/GraphEditor/GraphNodeMessage.vue'
import GraphVisualization from '@/components/GraphEditor/GraphVisualization.vue'
import NodeWidgetTree from '@/components/GraphEditor/NodeWidgetTree.vue'
import SvgIcon from '@/components/SvgIcon.vue'
import { useApproach } from '@/composables/animation'
import { useDoubleClick } from '@/composables/doubleClick'
import { usePointer, useResizeObserver } from '@/composables/events'
Expand Down Expand Up @@ -117,7 +118,7 @@ const warning = computed(() => {
const info = projectStore.computedValueRegistry.db.get(externalId)
const warning = info?.payload.type === 'Value' ? info.payload.warnings?.value : undefined
if (!warning) return
return 'Warning: ' + warning!
return 'Warning: ' + warning!
})

const isSelected = computed(() => nodeSelection?.isSelected(nodeId.value) ?? false)
Expand Down Expand Up @@ -448,12 +449,16 @@ const documentation = computed<string | undefined>(() => props.node.documentatio
@openFullMenu="openFullMenu"
/>
</div>
<div class="statuses">
<SvgIcon v-if="warning" name="warning" />
</div>
<GraphNodeError v-if="error" class="afterNode" :message="error" type="error" />
<GraphNodeError
v-if="warning && (nodeHovered || isSelected)"
class="afterNode warning"
:class="menuVisible === MenuState.Off ? '' : 'messageWithMenu'"
:class="{ messageWithMenu: menuVisible !== MenuState.Off }"
:message="warning"
icon="warning"
type="warning"
/>
<svg class="bgPaths" :style="bgStyleVariables">
Expand Down Expand Up @@ -685,11 +690,30 @@ const documentation = computed<string | undefined>(() => props.node.documentatio
margin-top: 4px;
}

.messageWarning {
margin-top: 8px;
}

.messageWithMenu {
left: 40px;
}

.warning {
top: 35px;
.statuses {
position: absolute;
pointer-events: none;
display: flex;
align-items: center;
gap: 4px;
height: 100%;
top: 0;
right: 100%;
margin-right: 8px;
color: var(--color-warning);
transition: opacity 0.2s ease-in-out;
}

.GraphNode:is(:hover, .selected) .statuses,
.GraphNode:has(.selection:hover) .statuses {
opacity: 0;
}
</style>
46 changes: 32 additions & 14 deletions app/gui2/src/components/GraphEditor/GraphNodeMessage.vue
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
<script setup lang="ts">
/// types of messages
import SvgIcon from '@/components/SvgIcon.vue'
import type { Icon } from '@/util/iconName'
import { computed } from 'vue'

/** The type of a message. */
export type GraphNodeMessageType = 'error' | 'warning'

const props = defineProps<{ message: string; type: GraphNodeMessageType }>()

function styleClassForType(type: GraphNodeMessageType) {
switch (type) {
case 'error':
return 'GraphNodeError'
case 'warning':
return 'GraphNodeWarning'
default:
return ''
}
const props = defineProps<{
message: string
type: GraphNodeMessageType
icon?: Icon
}>()

const icon = computed(() => iconForType[props.type])
</script>

<script lang="ts">
const styleClassForType: Record<GraphNodeMessageType, string> = {
error: 'GraphNodeError',
warning: 'GraphNodeWarning',
}

const iconForType: Record<GraphNodeMessageType, Icon | undefined> = {
error: 'error',
warning: 'warning',
}
</script>

<template>
<div class="GraphNodeMessage" :class="styleClassForType(props.type)" v-text="props.message"></div>
<div class="GraphNodeMessage" :class="styleClassForType[props.type]">
<SvgIcon class="icon" :name="icon" />
<div v-text="props.message"></div>
</div>
</template>

<style scoped>
Expand All @@ -26,7 +40,7 @@ function styleClassForType(type: GraphNodeMessageType) {
height: 24px;
padding: 1px 8px;
align-items: flex-start;
gap: 10px;
gap: 6px;
font-weight: 800;
white-space: nowrap;
border-radius: var(--radius-full);
Expand All @@ -41,4 +55,8 @@ function styleClassForType(type: GraphNodeMessageType) {
.GraphNodeError {
background-color: #e85252;
}

.icon {
margin: auto 0;
}
</style>
2 changes: 2 additions & 0 deletions app/gui2/src/util/specialCharacters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/** A non-breaking space. Useful for displaying multiple spaces in a row in HTML. */
export const nbsp = '\xa0'
Loading