93 lines
2.1 KiB
Vue
93 lines
2.1 KiB
Vue
<template>
|
||
<div class="s8n-calculator q-pa-md">
|
||
<div class="q-gutter-md">
|
||
<q-select
|
||
outlined
|
||
v-model="inputs.operator"
|
||
label="Operator"
|
||
:options="[
|
||
{ label: 'Add (+)', value: 'add' },
|
||
{ label: 'Subtract (-)', value: 'subtract' },
|
||
{ label: 'Multiply (×)', value: 'multiply' },
|
||
{ label: 'Divide (÷)', value: 'divide' },
|
||
]"
|
||
emit-value
|
||
map-options
|
||
/>
|
||
<q-input
|
||
v-for="(a, aidx) in inputs.args"
|
||
:key="aidx"
|
||
outlined
|
||
v-model.number="inputs.args[aidx]"
|
||
:label="`${aidx === 0 ? 'Base' : aidx === 1 ? 'Second' : aidx === 2 ? 'Third' : `${aidx + 1}th`} Number`"
|
||
type="number"
|
||
>
|
||
<template v-slot:after>
|
||
<q-btn
|
||
v-if="aidx > 1"
|
||
@click="inputs.args.splice(aidx, 1)"
|
||
class="col-auto"
|
||
icon="mdi-delete"
|
||
color="negative"
|
||
outline
|
||
dense
|
||
></q-btn>
|
||
</template>
|
||
</q-input>
|
||
|
||
<q-btn icon="mdi-plus" @click="inputs.args[inputs.args.length] = 0"></q-btn>
|
||
|
||
<div class="result-section q-mt-md">
|
||
<q-banner v-if="error" class="bg-negative text-white" rounded>
|
||
{{ error }}
|
||
</q-banner>
|
||
<div v-else-if="outputs !== undefined" class="text-h5 text-primary">
|
||
Result: {{ outputs.result }} ({{ duration }}ms)
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { runtime } from '../components/s8n-runtime';
|
||
|
||
const { execute, statusCode, running, error, duration, outputs, inputs } = runtime.createExecutor<
|
||
{
|
||
operator: string;
|
||
args: number[];
|
||
},
|
||
{
|
||
result?: number;
|
||
}
|
||
>('S8n.Components.Basics.Calculator', {
|
||
operator: 'add',
|
||
args: [0, 0],
|
||
});
|
||
|
||
defineExpose({
|
||
execute,
|
||
running,
|
||
error,
|
||
duration,
|
||
outputs,
|
||
inputs,
|
||
statusCode,
|
||
});
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.s8n-calculator {
|
||
max-width: 400px;
|
||
width: 100%;
|
||
|
||
.result-section {
|
||
min-height: 60px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
}
|
||
</style>
|