mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-02 07:01:30 -08:00
refactor header
This commit is contained in:
parent
865b795733
commit
56f02b3362
|
@ -0,0 +1,57 @@
|
|||
<template>
|
||||
<label role="radio" tabindex="-1" :class="$style.container" aria-checked="true">
|
||||
<input type="radio" tabindex="-1" autocomplete="off" :class="$style.input" :value="value">
|
||||
<div :class="{[$style.button]: true, [$style.active]: active}" @click="$emit('click')">{{ label }}</div>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'n8n-radio-button',
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.container {
|
||||
display: inline-block;
|
||||
outline: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.input {
|
||||
opacity: 0;
|
||||
outline: 0;
|
||||
z-index: -1;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.button {
|
||||
border-radius: 0;
|
||||
padding: var(--spacing-2xs) 15px;
|
||||
font-size: var(--font-size-2xs);
|
||||
border-radius: var(--border-radius-base);
|
||||
font-weight: var(--font-weight-bold);
|
||||
color: var(--color-text-base);
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: var(--color-foreground-xlight);
|
||||
color: var(--color-text-dark);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,51 @@
|
|||
import N8nRadioButtons from './RadioButtons.vue';
|
||||
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
export default {
|
||||
title: 'Atoms/RadioButtons',
|
||||
component: N8nRadioButtons,
|
||||
argTypes: {
|
||||
},
|
||||
parameters: {
|
||||
backgrounds: { default: '--color-background-xlight' },
|
||||
},
|
||||
};
|
||||
|
||||
const methods = {
|
||||
onInput: action('input'),
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nRadioButtons,
|
||||
},
|
||||
template:
|
||||
`<n8n-radio-buttons v-model="val" v-bind="$props" @input="onInput">
|
||||
</n8n-radio-buttons>`,
|
||||
methods,
|
||||
data() {
|
||||
return {
|
||||
val: '',
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const Example = Template.bind({});
|
||||
Example.args = {
|
||||
options: [
|
||||
{
|
||||
label: 'Test',
|
||||
value: 'test',
|
||||
},
|
||||
{
|
||||
label: 'World',
|
||||
value: 'world',
|
||||
},
|
||||
{
|
||||
label: 'Hello',
|
||||
value: 'hello',
|
||||
},
|
||||
],
|
||||
};
|
|
@ -0,0 +1,49 @@
|
|||
<template>
|
||||
<div role="radiogroup" :class="$style.radioGroup">
|
||||
<RadioButton
|
||||
v-for="option in options"
|
||||
:key="option.value"
|
||||
v-bind="option"
|
||||
:active="value === option.value"
|
||||
@click="(e) => onClick(option.value, e)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import RadioButton from './RadioButton';
|
||||
|
||||
export default {
|
||||
name: 'n8n-radio-buttons',
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
},
|
||||
options: {
|
||||
},
|
||||
},
|
||||
components: {
|
||||
RadioButton,
|
||||
},
|
||||
methods: {
|
||||
onClick(value) {
|
||||
this.$emit('input', value);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
|
||||
.radioGroup {
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
vertical-align: middle;
|
||||
font-size: 0;
|
||||
background-color: var(--color-foreground-base);
|
||||
padding: var(--spacing-5xs);
|
||||
border-radius: var(--border-radius-base);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import N8nRadioButtons from './RadioButtons.vue';
|
||||
|
||||
export default N8nRadioButtons;
|
|
@ -53,6 +53,7 @@ import N8nMenu from './N8nMenu';
|
|||
import N8nMenuItem from './N8nMenuItem';
|
||||
import N8nLink from './N8nLink';
|
||||
import N8nOption from './N8nOption';
|
||||
import N8nRadioButtons from './N8nRadioButtons';
|
||||
import N8nSelect from './N8nSelect';
|
||||
import N8nSpinner from './N8nSpinner';
|
||||
import N8nSquareButton from './N8nSquareButton';
|
||||
|
@ -87,6 +88,7 @@ export {
|
|||
N8nMenu,
|
||||
N8nMenuItem,
|
||||
N8nOption,
|
||||
N8nRadioButtons,
|
||||
N8nSelect,
|
||||
N8nSpinner,
|
||||
N8nSquareButton,
|
||||
|
|
|
@ -285,8 +285,8 @@
|
|||
);
|
||||
|
||||
--color-background-light-h: 220;
|
||||
--color-background-light-s: 27.3%;
|
||||
--color-background-light-l: 97.8%;
|
||||
--color-background-light-s: 60%;
|
||||
--color-background-light-l: 99%;
|
||||
--color-background-light: hsl(
|
||||
var(--color-background-light-h),
|
||||
var(--color-background-light-s),
|
||||
|
|
|
@ -1,10 +1,23 @@
|
|||
<template>
|
||||
<div class="run-data-view" v-loading="workflowRunning">
|
||||
<div :class="['run-data-view', $style.container]" v-loading="workflowRunning">
|
||||
<BinaryDataDisplay :windowVisible="binaryDataDisplayVisible" :displayData="binaryDataDisplayData" @close="closeBinaryDataDisplay"/>
|
||||
|
||||
<div class="header">
|
||||
<div :class="$style.header">
|
||||
<div>
|
||||
<span :class="$style.title">{{ $locale.baseText('runData.output') }}</span>
|
||||
<n8n-tooltip
|
||||
v-if="runMetadata"
|
||||
placement="right"
|
||||
>
|
||||
<div slot="content">
|
||||
<n8n-text :bold="true" size="small">{{ $locale.baseText('runData.startTime') + ':' }}</n8n-text> {{runMetadata.startTime}}<br/>
|
||||
<n8n-text :bold="true" size="small">{{ $locale.baseText('runData.executionTime') + ':' }}</n8n-text> {{runMetadata.executionTime}} {{ $locale.baseText('runData.ms') }}
|
||||
</div>
|
||||
<font-awesome-icon icon="info-circle" :class="$style.infoIcon" />
|
||||
</n8n-tooltip>
|
||||
</div>
|
||||
<div class="title-text">
|
||||
<n8n-text :bold="true" v-if="dataCount < maxDisplayItems">
|
||||
<!-- <n8n-text :bold="true" v-if="dataCount < maxDisplayItems">
|
||||
{{ $locale.baseText('runData.items') }}: {{ dataCount }}
|
||||
</n8n-text>
|
||||
<div v-else class="title-text">
|
||||
|
@ -15,20 +28,11 @@
|
|||
</n8n-select>
|
||||
</span>/
|
||||
<n8n-text :bold="true">{{ dataCount }}</n8n-text>
|
||||
</div>
|
||||
<n8n-tooltip
|
||||
v-if="runMetadata"
|
||||
placement="right"
|
||||
>
|
||||
<div slot="content">
|
||||
<n8n-text :bold="true" size="small">{{ $locale.baseText('runData.startTime') + ':' }}</n8n-text> {{runMetadata.startTime}}<br/>
|
||||
<n8n-text :bold="true" size="small">{{ $locale.baseText('runData.executionTime') + ':' }}</n8n-text> {{runMetadata.executionTime}} {{ $locale.baseText('runData.ms') }}
|
||||
</div>
|
||||
<font-awesome-icon icon="info-circle" class="primary-color" />
|
||||
</n8n-tooltip>
|
||||
<n8n-text :bold="true" v-if="maxOutputIndex > 0">
|
||||
</div> -->
|
||||
|
||||
<!-- <n8n-text :bold="true" v-if="maxOutputIndex > 0">
|
||||
| {{ $locale.baseText('runData.output') }}:
|
||||
</n8n-text>
|
||||
</n8n-text> -->
|
||||
<span class="opts" v-if="maxOutputIndex > 0" >
|
||||
<n8n-select size="mini" v-model="outputIndex" @click.stop>
|
||||
<n8n-option v-for="option in (maxOutputIndex + 1)" :label="getOutputName(option-1)" :value="option -1" :key="option">
|
||||
|
@ -48,13 +52,12 @@
|
|||
|
||||
</div>
|
||||
<div v-if="hasNodeRun && !hasRunError" class="title-data-display-selector" @click.stop>
|
||||
<el-radio-group v-model="displayMode" size="mini">
|
||||
<el-radio-button :label="$locale.baseText('runData.json')" :disabled="showData === false"></el-radio-button>
|
||||
<el-radio-button :label="$locale.baseText('runData.table')"></el-radio-button>
|
||||
<el-radio-button :label="$locale.baseText('runData.binary')" v-if="binaryData.length !== 0"></el-radio-button>
|
||||
</el-radio-group>
|
||||
<n8n-radio-buttons
|
||||
v-model="displayMode"
|
||||
:options="buttons"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="hasNodeRun && !hasRunError && displayMode === $locale.baseText('runData.json') && state.path !== deselectedPlaceholder" class="select-button">
|
||||
<div v-if="hasNodeRun && !hasRunError && displayMode === 'json' && state.path !== deselectedPlaceholder" class="select-button">
|
||||
<el-dropdown trigger="click" @command="handleCopyClick">
|
||||
<span class="el-dropdown-link">
|
||||
<n8n-icon-button :title="$locale.baseText('runData.copyToClipboard')" icon="copy" />
|
||||
|
@ -98,14 +101,14 @@
|
|||
<n8n-button
|
||||
icon="eye"
|
||||
:label="$locale.baseText('runData.displayDataAnyway')"
|
||||
@click="displayMode = $locale.baseText('runData.table');showData = true;"
|
||||
@click="displayMode = 'table';showData = true;"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="[$locale.baseText('runData.json'), $locale.baseText('runData.table')].includes(displayMode)">
|
||||
<div v-else-if="['json', 'table'].includes(displayMode)">
|
||||
<div v-if="jsonData.length === 0" class="no-data">
|
||||
{{ $locale.baseText('runData.noTextDataFound') }}
|
||||
</div>
|
||||
<div v-else-if="displayMode === $locale.baseText('runData.table')">
|
||||
<div v-else-if="displayMode === 'table'">
|
||||
<div v-if="tableData !== null && tableData.columns.length === 0" class="no-data">
|
||||
{{ $locale.baseText('runData.entriesExistButThey') }}
|
||||
</div>
|
||||
|
@ -119,7 +122,7 @@
|
|||
</table>
|
||||
</div>
|
||||
<vue-json-pretty
|
||||
v-else-if="displayMode === $locale.baseText('runData.json')"
|
||||
v-else-if="displayMode === 'json'"
|
||||
:data="jsonData"
|
||||
:deep="10"
|
||||
v-model="state.path"
|
||||
|
@ -133,7 +136,7 @@
|
|||
class="json-data"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="displayMode === $locale.baseText('runData.binary')">
|
||||
<div v-else-if="displayMode === 'binary'">
|
||||
<div v-if="binaryData.length === 0" class="no-data">
|
||||
{{ $locale.baseText('runData.noBinaryDataFound') }}
|
||||
</div>
|
||||
|
@ -249,7 +252,7 @@ export default mixins(
|
|||
binaryDataPreviewActive: false,
|
||||
dataSize: 0,
|
||||
deselectedPlaceholder,
|
||||
displayMode: this.$locale.baseText('runData.table'),
|
||||
displayMode: 'table',
|
||||
state: {
|
||||
value: '' as object | number | string,
|
||||
path: deselectedPlaceholder,
|
||||
|
@ -269,6 +272,19 @@ export default mixins(
|
|||
this.init();
|
||||
},
|
||||
computed: {
|
||||
buttons(): {label: string, value: string}[] {
|
||||
const defaults = [
|
||||
{ label: this.$locale.baseText('runData.json'), value: 'json'},
|
||||
{ label: this.$locale.baseText('runData.table'), value: 'table'},
|
||||
];
|
||||
if (this.binaryData.length) {
|
||||
return [ ...defaults,
|
||||
{ label: this.$locale.baseText('runData.binary'), value: 'binary'},
|
||||
];
|
||||
}
|
||||
|
||||
return defaults;
|
||||
},
|
||||
hasNodeRun(): boolean {
|
||||
return Boolean(this.node && this.workflowRunData && this.workflowRunData.hasOwnProperty(this.node.name));
|
||||
},
|
||||
|
@ -426,10 +442,10 @@ export default mixins(
|
|||
this.outputIndex = 0;
|
||||
this.maxDisplayItems = 25;
|
||||
this.refreshDataSize();
|
||||
if (this.displayMode === this.$locale.baseText('runData.binary')) {
|
||||
if (this.displayMode === 'binary') {
|
||||
this.closeBinaryDataDisplay();
|
||||
if (this.binaryData.length === 0) {
|
||||
this.displayMode = this.$locale.baseText('runData.table');
|
||||
this.displayMode = 'table';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -638,13 +654,40 @@ export default mixins(
|
|||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
<style lang="scss" module>
|
||||
.infoIcon {
|
||||
color: var(--color-foreground-dark);
|
||||
}
|
||||
|
||||
.run-data-view {
|
||||
.title {
|
||||
text-transform: uppercase;
|
||||
color: var(--color-text-light);
|
||||
letter-spacing: 3px;
|
||||
font-weight: var(--font-weight-bold);
|
||||
margin-right: var(--spacing-2xs);
|
||||
}
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f9f9f9;
|
||||
background-color: var(--color-background-light);
|
||||
padding: var(--spacing-s) var(--spacing-s) 0 var(--spacing-s);
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
> *:first-child {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
.run-data-view {
|
||||
|
||||
.data-display-content {
|
||||
position: absolute;
|
||||
|
@ -767,50 +810,47 @@ export default mixins(
|
|||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
padding-top: 10px;
|
||||
padding-left: 10px;
|
||||
// .header {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// height: 40px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
// .select-button {
|
||||
// height: 30px;
|
||||
// top: 50px;
|
||||
// right: 30px;
|
||||
// position: absolute;
|
||||
// text-align: right;
|
||||
// width: 200px;
|
||||
// z-index: 10;
|
||||
// }
|
||||
|
||||
.select-button {
|
||||
height: 30px;
|
||||
top: 50px;
|
||||
right: 30px;
|
||||
position: absolute;
|
||||
text-align: right;
|
||||
width: 200px;
|
||||
z-index: 10;
|
||||
}
|
||||
// .title-text {
|
||||
// display: inline-flex;
|
||||
// align-items: center;
|
||||
|
||||
.title-text {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
// > * {
|
||||
// margin-right: 2px;
|
||||
// }
|
||||
// }
|
||||
|
||||
> * {
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
// .title-data-display-selector {
|
||||
// position: absolute;
|
||||
// left: calc(50% - 105px);
|
||||
// width: 210px;
|
||||
// display: inline-block;
|
||||
// text-align: center;
|
||||
|
||||
.title-data-display-selector {
|
||||
position: absolute;
|
||||
left: calc(50% - 105px);
|
||||
width: 210px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
// .entry.active {
|
||||
// font-weight: bold;
|
||||
// }
|
||||
// }
|
||||
|
||||
.entry.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.opts {
|
||||
width: 80px;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
// .opts {
|
||||
// width: 80px;
|
||||
// z-index: 1;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -61,6 +61,7 @@ import {
|
|||
N8nMenu,
|
||||
N8nMenuItem,
|
||||
N8nOption,
|
||||
N8nRadioButtons,
|
||||
N8nSelect,
|
||||
N8nSpinner,
|
||||
N8nFormInputs,
|
||||
|
@ -97,6 +98,7 @@ Vue.use(N8nMenuItem);
|
|||
Vue.use(N8nOption);
|
||||
Vue.use(N8nSelect);
|
||||
Vue.use(N8nSpinner);
|
||||
Vue.use(N8nRadioButtons);
|
||||
Vue.component('n8n-square-button', N8nSquareButton);
|
||||
Vue.use(N8nTags);
|
||||
Vue.use(N8nTag);
|
||||
|
|
Loading…
Reference in a new issue