mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 04:34:06 -08:00
fix(editor): Fix design system typecheck errors (no-changelog) (#9447)
This commit is contained in:
parent
d21ad15c1f
commit
eef5479e96
|
@ -3,6 +3,7 @@ import { computed, ref } from 'vue';
|
|||
import { uid } from '../../utils';
|
||||
import { ElColorPicker } from 'element-plus';
|
||||
import N8nInput from '../N8nInput';
|
||||
import type { ElementPlusSizePropType } from '@/types';
|
||||
|
||||
export type ColorPickerProps = {
|
||||
disabled?: boolean;
|
||||
|
@ -19,10 +20,12 @@ export type ColorPickerProps = {
|
|||
defineOptions({ name: 'N8nColorPicker' });
|
||||
const props = withDefaults(defineProps<ColorPickerProps>(), {
|
||||
disabled: false,
|
||||
size: 'medium',
|
||||
size: 'default',
|
||||
showAlpha: false,
|
||||
colorFormat: 'hex',
|
||||
popperClass: '',
|
||||
predefine: undefined,
|
||||
modelValue: undefined,
|
||||
showInput: true,
|
||||
name: uid('color-picker'),
|
||||
});
|
||||
|
@ -30,7 +33,7 @@ const props = withDefaults(defineProps<ColorPickerProps>(), {
|
|||
const color = ref(props.modelValue);
|
||||
|
||||
const colorPickerProps = computed(() => {
|
||||
const { showInput, ...rest } = props;
|
||||
const { showInput, modelValue, size, ...rest } = props;
|
||||
return rest;
|
||||
});
|
||||
|
||||
|
@ -40,6 +43,8 @@ const emit = defineEmits<{
|
|||
(event: 'active-change', value: string): void;
|
||||
}>();
|
||||
|
||||
const resolvedSize = computed(() => props.size as ElementPlusSizePropType);
|
||||
|
||||
const onChange = (value: string) => {
|
||||
emit('change', value);
|
||||
};
|
||||
|
@ -61,7 +66,7 @@ const onColorSelect = (value: string) => {
|
|||
<span :class="['n8n-color-picker', $style.component]">
|
||||
<ElColorPicker
|
||||
v-bind="colorPickerProps"
|
||||
size="default"
|
||||
:size="resolvedSize"
|
||||
@change="onChange"
|
||||
@active-change="onActiveChange"
|
||||
@update:model-value="onColorSelect"
|
||||
|
@ -70,7 +75,7 @@ const onColorSelect = (value: string) => {
|
|||
v-if="showInput"
|
||||
:class="$style.input"
|
||||
:disabled="props.disabled"
|
||||
:size="props.size"
|
||||
:size="size"
|
||||
:model-value="color"
|
||||
:name="name"
|
||||
type="text"
|
||||
|
|
|
@ -64,7 +64,7 @@ exports[`components > N8nColorPicker > should render with input 1`] = `
|
|||
<!--teleport end-->
|
||||
|
||||
<div
|
||||
class="el-input el-input--medium n8n-input input input"
|
||||
class="el-input el-input--default n8n-input input input"
|
||||
data-v-dab78bb8=""
|
||||
>
|
||||
<!-- input -->
|
||||
|
@ -79,7 +79,6 @@ exports[`components > N8nColorPicker > should render with input 1`] = `
|
|||
<input
|
||||
autocomplete="off"
|
||||
class="el-input__inner"
|
||||
maxlength="Infinity"
|
||||
name="color-picker"
|
||||
placeholder=""
|
||||
rows="2"
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
<template>
|
||||
<N8nCheckbox
|
||||
v-if="type === 'checkbox'"
|
||||
v-bind="$props"
|
||||
ref="inputRef"
|
||||
:label="label"
|
||||
:disabled="disabled"
|
||||
:label-size="labelSize as CheckboxLabelSizePropType"
|
||||
:model-value="modelValue as CheckboxModelValuePropType"
|
||||
@update:model-value="onUpdateModelValue"
|
||||
@focus="onFocus"
|
||||
/>
|
||||
|
@ -17,7 +20,7 @@
|
|||
{{ tooltipText }}
|
||||
</template>
|
||||
<ElSwitch
|
||||
:model-value="modelValue"
|
||||
:model-value="modelValue as SwitchModelValuePropType"
|
||||
:active-color="activeColor"
|
||||
:inactive-color="inactiveColor"
|
||||
@update:model-value="onUpdateModelValue"
|
||||
|
@ -59,9 +62,9 @@
|
|||
v-else
|
||||
ref="inputRef"
|
||||
:name="name"
|
||||
:type="type"
|
||||
:type="type as InputTypePropType"
|
||||
:placeholder="placeholder"
|
||||
:model-value="modelValue"
|
||||
:model-value="modelValue as InputModelValuePropType"
|
||||
:maxlength="maxlength"
|
||||
:autocomplete="autocomplete"
|
||||
:disabled="disabled"
|
||||
|
@ -99,7 +102,18 @@ import N8nCheckbox from '../N8nCheckbox';
|
|||
import { ElSwitch } from 'element-plus';
|
||||
|
||||
import { getValidationError, VALIDATORS } from './validators';
|
||||
import type { Rule, RuleGroup, IValidator, Validatable, FormState } from '../../types';
|
||||
import type {
|
||||
Rule,
|
||||
RuleGroup,
|
||||
IValidator,
|
||||
Validatable,
|
||||
InputModelValuePropType,
|
||||
InputTypePropType,
|
||||
SwitchModelValuePropType,
|
||||
CheckboxModelValuePropType,
|
||||
CheckboxLabelSizePropType,
|
||||
InputAutocompletePropType,
|
||||
} from '../../types';
|
||||
|
||||
import { t } from '../../locale';
|
||||
|
||||
|
@ -120,10 +134,10 @@ export interface Props {
|
|||
validators?: { [key: string]: IValidator | RuleGroup };
|
||||
maxlength?: number;
|
||||
options?: Array<{ value: string | number; label: string; disabled?: boolean }>;
|
||||
autocomplete?: string;
|
||||
autocomplete?: InputAutocompletePropType;
|
||||
name?: string;
|
||||
focusInitially?: boolean;
|
||||
labelSize?: 'small' | 'medium';
|
||||
labelSize?: 'small' | 'medium' | 'large';
|
||||
disabled?: boolean;
|
||||
activeLabel?: string;
|
||||
activeColor?: string;
|
||||
|
@ -206,7 +220,7 @@ function onBlur() {
|
|||
$emit('blur');
|
||||
}
|
||||
|
||||
function onUpdateModelValue(value: FormState) {
|
||||
function onUpdateModelValue(value: Validatable) {
|
||||
state.isTyping = true;
|
||||
$emit('update:modelValue', value);
|
||||
}
|
||||
|
@ -225,9 +239,9 @@ const validationError = computed<string | null>(() => {
|
|||
const error = getInputValidationError();
|
||||
|
||||
if (error) {
|
||||
if (error.messageKey) {
|
||||
return t(error.messageKey, error.options);
|
||||
} else {
|
||||
if ('messageKey' in error) {
|
||||
return t(error.messageKey, error.options as object);
|
||||
} else if ('message' in error) {
|
||||
return error.message;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ export const requiredValidator: IValidator<{}> = {
|
|||
};
|
||||
|
||||
export const minLengthValidator: IValidator<{ minimum: number }> = {
|
||||
validate: (value: Validatable, config: { minimum: number }) => {
|
||||
validate: (value: Validatable, config) => {
|
||||
if (typeof value === 'string' && value.length < config.minimum) {
|
||||
return {
|
||||
messageKey: 'formInput.validator.minCharactersRequired',
|
||||
|
@ -76,7 +76,7 @@ export const emailValidator: IValidator<{}> = {
|
|||
};
|
||||
|
||||
export const containsUpperCaseValidator: IValidator<{ minimum: number }> = {
|
||||
validate: (value: Validatable, config: { minimum: number }) => {
|
||||
validate: (value: Validatable, config) => {
|
||||
if (typeof value !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ export const containsUpperCaseValidator: IValidator<{ minimum: number }> = {
|
|||
};
|
||||
|
||||
export const matchRegex: IValidator<{ regex: RegExp; message: string }> = {
|
||||
validate: (value: Validatable, config: { regex: RegExp; message: string }) => {
|
||||
validate: (value: Validatable, config) => {
|
||||
if (!config.regex.test(`${value as string}`)) {
|
||||
return {
|
||||
message: config.message,
|
||||
|
|
|
@ -75,7 +75,7 @@ export default defineComponent({
|
|||
default: true,
|
||||
},
|
||||
tagSize: {
|
||||
type: String,
|
||||
type: String as PropType<'small' | 'medium'>,
|
||||
default: 'small',
|
||||
validator: (value: string): boolean => ['small', 'medium'].includes(value),
|
||||
},
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
<template>
|
||||
<ElInput
|
||||
ref="innerInput"
|
||||
:size="computedSize"
|
||||
:model-value="modelValue"
|
||||
:type="type"
|
||||
:size="resolvedSize"
|
||||
:class="['n8n-input', ...classes]"
|
||||
:autocomplete="autocomplete"
|
||||
:name="name"
|
||||
v-bind="{ ...$props, ...$attrs }"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
:clearable="clearable"
|
||||
:rows="rows"
|
||||
:title="title"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<template v-if="$slots.prepend" #prepend>
|
||||
<slot name="prepend" />
|
||||
|
@ -27,6 +35,7 @@ import { computed, ref } from 'vue';
|
|||
import { ElInput } from 'element-plus';
|
||||
import { uid } from '../../utils';
|
||||
import type { InputSize, InputType } from '@/types/input';
|
||||
import type { ElementPlusSizePropType, InputAutocompletePropType } from '@/types';
|
||||
|
||||
interface InputProps {
|
||||
modelValue?: string | number;
|
||||
|
@ -40,12 +49,13 @@ interface InputProps {
|
|||
maxlength?: number;
|
||||
title?: string;
|
||||
name?: string;
|
||||
autocomplete?: 'off' | 'autocomplete';
|
||||
autocomplete?: InputAutocompletePropType;
|
||||
}
|
||||
|
||||
defineOptions({ name: 'N8nInput' });
|
||||
const props = withDefaults(defineProps<InputProps>(), {
|
||||
modelValue: '',
|
||||
type: 'text',
|
||||
size: 'large',
|
||||
placeholder: '',
|
||||
disabled: false,
|
||||
|
@ -58,7 +68,9 @@ const props = withDefaults(defineProps<InputProps>(), {
|
|||
autocomplete: 'off',
|
||||
});
|
||||
|
||||
const computedSize = computed(() => (props.size === 'xlarge' ? undefined : props.size));
|
||||
const resolvedSize = computed(
|
||||
() => (props.size === 'xlarge' ? undefined : props.size) as ElementPlusSizePropType,
|
||||
);
|
||||
|
||||
const classes = computed(() => {
|
||||
const applied: string[] = [];
|
||||
|
|
|
@ -7,7 +7,7 @@ exports[`N8nInput > should render correctly 1`] = `
|
|||
<!--v-if-->
|
||||
<div class="el-input__wrapper">
|
||||
<!-- prefix slot -->
|
||||
<!--v-if--><input class="el-input__inner" name="input" rows="2" maxlength="Infinity" title="" type="text" autocomplete="off" tabindex="0" placeholder=""><!-- suffix slot -->
|
||||
<!--v-if--><input class="el-input__inner" name="input" rows="2" title="" type="text" autocomplete="off" tabindex="0" placeholder=""><!-- suffix slot -->
|
||||
<!--v-if-->
|
||||
</div><!-- append slot -->
|
||||
<!--v-if-->
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import type { InputSize } from '@/types';
|
||||
import type { ElementPlusSizePropType, InputSize } from '@/types';
|
||||
import { ElInputNumber } from 'element-plus';
|
||||
import { computed } from 'vue';
|
||||
|
||||
type InputNumberProps = {
|
||||
size?: InputSize;
|
||||
|
@ -10,9 +11,24 @@ type InputNumberProps = {
|
|||
precision?: number;
|
||||
};
|
||||
|
||||
defineProps<InputNumberProps>();
|
||||
const props = withDefaults(defineProps<InputNumberProps>(), {
|
||||
size: undefined,
|
||||
step: 1,
|
||||
precision: 0,
|
||||
min: -Infinity,
|
||||
max: Infinity,
|
||||
});
|
||||
|
||||
const resolvedSize = computed(() => props.size as ElementPlusSizePropType);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ElInputNumber v-bind="{ ...$props, ...$attrs }" />
|
||||
<ElInputNumber
|
||||
:size="resolvedSize"
|
||||
:min="min"
|
||||
:max="max"
|
||||
:step="step"
|
||||
:precision="precision"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -17,7 +17,7 @@ import type { TextSize } from '@/types/text';
|
|||
const THEME = ['primary', 'danger', 'text', 'secondary'] as const;
|
||||
|
||||
interface LinkProps {
|
||||
to?: RouteLocationRaw;
|
||||
to?: RouteLocationRaw | string;
|
||||
size?: TextSize;
|
||||
newWindow?: boolean;
|
||||
bold?: boolean;
|
||||
|
@ -27,6 +27,8 @@ interface LinkProps {
|
|||
|
||||
defineOptions({ name: 'N8nLink' });
|
||||
withDefaults(defineProps<LinkProps>(), {
|
||||
to: undefined,
|
||||
size: undefined,
|
||||
bold: false,
|
||||
underline: false,
|
||||
theme: 'primary',
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<template #content>{{ nodeTypeName }}</template>
|
||||
<div v-if="type !== 'unknown'" :class="$style.icon">
|
||||
<img v-if="type === 'file'" :src="src" :class="$style.nodeIconImage" />
|
||||
<FontAwesomeIcon v-else :icon="name" :class="$style.iconFa" :style="fontStyleData" />
|
||||
<FontAwesomeIcon v-else :icon="`${name}`" :class="$style.iconFa" :style="fontStyleData" />
|
||||
</div>
|
||||
<div v-else :class="$style.nodeIconPlaceholder">
|
||||
{{ nodeTypeName ? nodeTypeName.charAt(0) : '?' }}
|
||||
|
@ -22,7 +22,7 @@
|
|||
<template v-else>
|
||||
<div v-if="type !== 'unknown'" :class="$style.icon">
|
||||
<img v-if="type === 'file'" :src="src" :class="$style.nodeIconImage" />
|
||||
<FontAwesomeIcon v-else :icon="name" :style="fontStyleData" />
|
||||
<FontAwesomeIcon v-else :icon="`${name}`" :style="fontStyleData" />
|
||||
<div v-if="badge" :class="$style.badge" :style="badgeStyleData">
|
||||
<n8n-node-icon :type="badge.type" :src="badge.src" :size="badgeSize"></n8n-node-icon>
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<template>
|
||||
<router-link v-if="useRouterLink" :to="to" v-bind="$attrs">
|
||||
<router-link v-if="useRouterLink && to" :to="to" v-bind="$attrs">
|
||||
<slot></slot>
|
||||
</router-link>
|
||||
<a v-else :href="to" :target="openNewWindow ? '_blank' : '_self'" v-bind="$attrs">
|
||||
<a
|
||||
v-else
|
||||
:href="to ? `${to}` : undefined"
|
||||
:target="openNewWindow ? '_blank' : '_self'"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<slot></slot>
|
||||
</a>
|
||||
</template>
|
||||
|
@ -12,7 +17,7 @@ import { computed } from 'vue';
|
|||
import { type RouteLocationRaw } from 'vue-router';
|
||||
|
||||
interface RouteProps {
|
||||
to?: RouteLocationRaw;
|
||||
to?: RouteLocationRaw | string;
|
||||
newWindow?: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
import { ElSelect } from 'element-plus';
|
||||
import { type PropType, defineComponent } from 'vue';
|
||||
import type { SelectSize } from '@/types';
|
||||
import { isEventBindingElementAttribute } from '../../utils';
|
||||
|
||||
type InnerSelectRef = InstanceType<typeof ElSelect>;
|
||||
|
||||
|
@ -86,13 +87,16 @@ export default defineComponent({
|
|||
},
|
||||
computed: {
|
||||
listeners() {
|
||||
return Object.entries(this.$attrs).reduce<Record<string, () => {}>>((acc, [key, value]) => {
|
||||
if (/^on[A-Z]/.test(key)) {
|
||||
acc[key] = value;
|
||||
}
|
||||
return Object.entries(this.$attrs).reduce<Record<string, (...args: unknown[]) => {}>>(
|
||||
(acc, [key, value]) => {
|
||||
if (isEventBindingElementAttribute(value, key)) {
|
||||
acc[key] = value;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
},
|
||||
computedSize(): InnerSelectRef['$props']['size'] {
|
||||
if (this.size === 'medium') {
|
||||
|
|
|
@ -13,8 +13,7 @@ export default {
|
|||
};
|
||||
|
||||
const methods = {
|
||||
onReinvite: action('reinvite'),
|
||||
onDelete: action('delete'),
|
||||
action: ({ action: actionName }: { action: string; userId: string }) => action(actionName),
|
||||
};
|
||||
|
||||
const Template: StoryFn = (args, { argTypes }) => ({
|
||||
|
@ -23,8 +22,7 @@ const Template: StoryFn = (args, { argTypes }) => ({
|
|||
components: {
|
||||
N8nUsersList,
|
||||
},
|
||||
template:
|
||||
'<n8n-users-list v-bind="args" :actions="actions" @reinvite="onReinvite" @delete="onDelete" />',
|
||||
template: '<n8n-users-list v-bind="args" :actions="actions" @action="action" />',
|
||||
methods,
|
||||
});
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ interface UsersListProps {
|
|||
|
||||
const props = withDefaults(defineProps<UsersListProps>(), {
|
||||
readonly: false,
|
||||
currentUserId: '',
|
||||
users: () => [],
|
||||
actions: () => [],
|
||||
isSamlLoginEnabled: false,
|
||||
|
@ -101,11 +102,15 @@ const defaultGuard = () => true;
|
|||
const getActions = (user: IUser): UserAction[] => {
|
||||
if (user.isOwner) return [];
|
||||
|
||||
return props.actions.filter((action) => (action.guard || defaultGuard)(user));
|
||||
return props.actions.filter((action) => (action.guard ?? defaultGuard)(user));
|
||||
};
|
||||
|
||||
const $emit = defineEmits(['*']);
|
||||
const onUserAction = (user: IUser, action: string) => $emit(action, user.id);
|
||||
const $emit = defineEmits(['action']);
|
||||
const onUserAction = (user: IUser, action: string) =>
|
||||
$emit('action', {
|
||||
action,
|
||||
userId: user.id,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { VNode } from 'vue';
|
||||
import type { Component, VNode } from 'vue';
|
||||
|
||||
export type DatatableRowDataType = string | number | boolean | null | undefined;
|
||||
|
||||
|
@ -14,5 +14,5 @@ export interface DatatableColumn {
|
|||
label: string;
|
||||
classes?: string[];
|
||||
width?: string;
|
||||
render?: (row: DatatableRow) => (() => VNode | VNode[]) | DatatableRowDataType;
|
||||
render?: Component | ((row: DatatableRow) => (() => VNode | VNode[]) | DatatableRowDataType);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,11 @@ export type IValidator<T = unknown> = {
|
|||
validate: (
|
||||
value: Validatable,
|
||||
config: T,
|
||||
) => false | { messageKey: string; message?: string; options?: unknown } | null;
|
||||
) =>
|
||||
| false
|
||||
| { message: string; options?: unknown }
|
||||
| { messageKey: string; options?: unknown }
|
||||
| null;
|
||||
};
|
||||
|
||||
export type FormState = {
|
||||
|
@ -45,13 +49,7 @@ export type IFormInput = {
|
|||
infoText?: string;
|
||||
placeholder?: string;
|
||||
options?: Array<{ label: string; value: string; disabled?: boolean }>;
|
||||
autocomplete?:
|
||||
| 'off'
|
||||
| 'new-password'
|
||||
| 'current-password'
|
||||
| 'given-name'
|
||||
| 'family-name'
|
||||
| 'email'; // https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
|
||||
autocomplete?: InputAutocompletePropType;
|
||||
capitalize?: boolean;
|
||||
focusInitially?: boolean;
|
||||
disabled?: boolean;
|
||||
|
@ -72,3 +70,17 @@ export type IFormBoxConfig = {
|
|||
redirectLink?: string;
|
||||
redirectText?: string;
|
||||
};
|
||||
|
||||
export type CheckboxLabelSizePropType = 'small' | 'medium' | undefined;
|
||||
export type CheckboxModelValuePropType = boolean | undefined;
|
||||
export type SwitchModelValuePropType = boolean | undefined;
|
||||
export type InputModelValuePropType = string | number | undefined;
|
||||
export type InputTypePropType = 'number' | 'text' | 'email' | 'password' | 'textarea' | undefined;
|
||||
export type InputAutocompletePropType =
|
||||
| 'off'
|
||||
| 'new-password'
|
||||
| 'current-password'
|
||||
| 'given-name'
|
||||
| 'family-name'
|
||||
| 'email'; // https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
|
||||
export type ElementPlusSizePropType = '' | 'small' | 'large' | 'default' | undefined;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export * from './event-bus';
|
||||
export * from './markdown';
|
||||
export * from './typeguards';
|
||||
export * from './uid';
|
||||
export * from './valueByPath';
|
||||
|
|
6
packages/design-system/src/utils/typeguards.ts
Normal file
6
packages/design-system/src/utils/typeguards.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export function isEventBindingElementAttribute(
|
||||
_attributeValue: unknown,
|
||||
attributeName: string,
|
||||
): _attributeValue is (...args: unknown[]) => {} {
|
||||
return /^on[A-Z]/.test(attributeName);
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
"allowSyntheticDefaultImports": true,
|
||||
"baseUrl": ".",
|
||||
"types": ["vitest/globals"],
|
||||
"typeRoots": ["@testing-library", "@types", "../../node_modules"],
|
||||
"typeRoots": ["./node_modules/@testing-library", "./node_modules/@types", "../../node_modules", "../../node_modules/@types"],
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
},
|
||||
|
|
|
@ -55,12 +55,7 @@
|
|||
:users="usersStore.allUsers"
|
||||
:current-user-id="usersStore.currentUserId"
|
||||
:is-saml-login-enabled="ssoStore.isSamlLoginEnabled"
|
||||
@delete="onDelete"
|
||||
@reinvite="onReinvite"
|
||||
@copy-invite-link="onCopyInviteLink"
|
||||
@copy-password-reset-link="onCopyPasswordResetLink"
|
||||
@allow-s-s-o-manual-login="onAllowSSOManualLogin"
|
||||
@disallow-s-s-o-manual-login="onDisallowSSOManualLogin"
|
||||
@action="onUsersListAction"
|
||||
>
|
||||
<template #actions="{ user }">
|
||||
<n8n-select
|
||||
|
@ -192,6 +187,28 @@ export default defineComponent({
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
async onUsersListAction({ action, userId }: { action: string; userId: string }) {
|
||||
switch (action) {
|
||||
case 'delete':
|
||||
await this.onDelete(userId);
|
||||
break;
|
||||
case 'reinvite':
|
||||
await this.onReinvite(userId);
|
||||
break;
|
||||
case 'copyInviteLink':
|
||||
await this.onCopyInviteLink(userId);
|
||||
break;
|
||||
case 'copyPasswordResetLink':
|
||||
await this.onCopyPasswordResetLink(userId);
|
||||
break;
|
||||
case 'allowSSOManualLogin':
|
||||
await this.onAllowSSOManualLogin(userId);
|
||||
break;
|
||||
case 'disallowSSOManualLogin':
|
||||
await this.onDisallowSSOManualLogin(userId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
redirectToSetup() {
|
||||
void this.$router.push({ name: VIEWS.SETUP });
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue