chore(plugin-workflow): adjust types (#2206)
* chore(plugin-workflow): adjust types * fix(plugin-workflow): fix types
This commit is contained in:
		
							parent
							
								
									2cb1203aa4
								
							
						
					
					
						commit
						6c19dad23d
					
				@ -1,8 +1,8 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "@nocobase/plugin-workflow",
 | 
					  "name": "@nocobase/plugin-workflow",
 | 
				
			||||||
  "displayName": "workflow",
 | 
					  "displayName": "Workflow",
 | 
				
			||||||
  "displayName.zh-CN": "工作流",
 | 
					  "displayName.zh-CN": "工作流",
 | 
				
			||||||
  "description": " a powerful workflow plugin designed to support business process management and automation. .",
 | 
					  "description": "A powerful workflow plugin designed to support business process management and automation.",
 | 
				
			||||||
  "description.zh-CN": "工作流插件,为业务流程管理和自动化提供支持。",
 | 
					  "description.zh-CN": "工作流插件,为业务流程管理和自动化提供支持。",
 | 
				
			||||||
  "version": "0.10.1-alpha.1",
 | 
					  "version": "0.10.1-alpha.1",
 | 
				
			||||||
  "license": "AGPL-3.0",
 | 
					  "license": "AGPL-3.0",
 | 
				
			||||||
@ -25,7 +25,8 @@
 | 
				
			|||||||
    "cron-parser": "4.4.0",
 | 
					    "cron-parser": "4.4.0",
 | 
				
			||||||
    "lru-cache": "8.0.5",
 | 
					    "lru-cache": "8.0.5",
 | 
				
			||||||
    "moment": "^2.29.2",
 | 
					    "moment": "^2.29.2",
 | 
				
			||||||
    "react-js-cron": "^3.1.0"
 | 
					    "react-js-cron": "^3.1.0",
 | 
				
			||||||
 | 
					    "sequelize": "^6.26.0"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "react": "18.x",
 | 
					    "react": "18.x",
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@ export * from './Branch';
 | 
				
			|||||||
export * from './FlowContext';
 | 
					export * from './FlowContext';
 | 
				
			||||||
export * from './nodes';
 | 
					export * from './nodes';
 | 
				
			||||||
export { triggers } from './triggers';
 | 
					export { triggers } from './triggers';
 | 
				
			||||||
 | 
					export { useWorkflowVariableOptions } from './variable';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { Plugin, useCollectionDataSource } from '@nocobase/client';
 | 
					import { Plugin, useCollectionDataSource } from '@nocobase/client';
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
 | 
				
			|||||||
@ -11,14 +11,13 @@ import initFields from './fields';
 | 
				
			|||||||
import initActions from './actions';
 | 
					import initActions from './actions';
 | 
				
			||||||
import { EXECUTION_STATUS } from './constants';
 | 
					import { EXECUTION_STATUS } from './constants';
 | 
				
			||||||
import initInstructions, { Instruction } from './instructions';
 | 
					import initInstructions, { Instruction } from './instructions';
 | 
				
			||||||
import ExecutionModel from './models/Execution';
 | 
					 | 
				
			||||||
import JobModel from './models/Job';
 | 
					 | 
				
			||||||
import WorkflowModel from './models/Workflow';
 | 
					 | 
				
			||||||
import Processor from './Processor';
 | 
					import Processor from './Processor';
 | 
				
			||||||
import initTriggers, { Trigger } from './triggers';
 | 
					import initTriggers, { Trigger } from './triggers';
 | 
				
			||||||
import initFunctions, { CustomFunction } from './functions';
 | 
					import initFunctions, { CustomFunction } from './functions';
 | 
				
			||||||
import { createLogger, Logger, LoggerOptions, getLoggerLevel, getLoggerFilePath } from '@nocobase/logger';
 | 
					import { createLogger, Logger, LoggerOptions, getLoggerLevel, getLoggerFilePath } from '@nocobase/logger';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import type { WorkflowModel, ExecutionModel, JobModel } from './types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Pending = [ExecutionModel, JobModel?];
 | 
					type Pending = [ExecutionModel, JobModel?];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ID = number | string;
 | 
					type ID = number | string;
 | 
				
			||||||
 | 
				
			|||||||
@ -5,9 +5,7 @@ import { parse } from '@nocobase/utils';
 | 
				
			|||||||
import Plugin from '.';
 | 
					import Plugin from '.';
 | 
				
			||||||
import { EXECUTION_STATUS, JOB_STATUS } from './constants';
 | 
					import { EXECUTION_STATUS, JOB_STATUS } from './constants';
 | 
				
			||||||
import { Runner } from './instructions';
 | 
					import { Runner } from './instructions';
 | 
				
			||||||
import ExecutionModel from './models/Execution';
 | 
					import type { ExecutionModel, FlowNodeModel, JobModel } from './types';
 | 
				
			||||||
import FlowNodeModel from './models/FlowNode';
 | 
					 | 
				
			||||||
import JobModel from './models/Job';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface ProcessorOptions extends Transactionable {
 | 
					export interface ProcessorOptions extends Transactionable {
 | 
				
			||||||
  plugin: Plugin;
 | 
					  plugin: Plugin;
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ import { lodash } from '@nocobase/utils';
 | 
				
			|||||||
import path from 'path';
 | 
					import path from 'path';
 | 
				
			||||||
import Plugin from '..';
 | 
					import Plugin from '..';
 | 
				
			||||||
import { JOB_STATUS } from '../constants';
 | 
					import { JOB_STATUS } from '../constants';
 | 
				
			||||||
import FlowNodeModel from '../models/FlowNode';
 | 
					import type { FlowNodeModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function sleep(ms: number) {
 | 
					export function sleep(ms: number) {
 | 
				
			||||||
  return new Promise((resolve) => {
 | 
					  return new Promise((resolve) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,14 +1,14 @@
 | 
				
			|||||||
import { Application } from '@nocobase/server';
 | 
					import { Application } from '@nocobase/server';
 | 
				
			||||||
import Database from '@nocobase/database';
 | 
					import Database from '@nocobase/database';
 | 
				
			||||||
import { getApp, sleep } from '..';
 | 
					import { getApp, sleep } from '..';
 | 
				
			||||||
import DefinedWorkflowModel from '../../models/Workflow';
 | 
					import type { WorkflowModel as WorkflowModelType } from '../../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('workflow > instructions > update', () => {
 | 
					describe('workflow > instructions > update', () => {
 | 
				
			||||||
  let app: Application;
 | 
					  let app: Application;
 | 
				
			||||||
  let db: Database;
 | 
					  let db: Database;
 | 
				
			||||||
  let PostRepo;
 | 
					  let PostRepo;
 | 
				
			||||||
  let WorkflowModel;
 | 
					  let WorkflowModel;
 | 
				
			||||||
  let workflow: DefinedWorkflowModel;
 | 
					  let workflow: WorkflowModelType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  beforeEach(async () => {
 | 
					  beforeEach(async () => {
 | 
				
			||||||
    app = await getApp();
 | 
					    app = await getApp();
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
import { Context, utils } from '@nocobase/actions';
 | 
					import { Context, utils } from '@nocobase/actions';
 | 
				
			||||||
import { MultipleRelationRepository, Op } from '@nocobase/database';
 | 
					import { MultipleRelationRepository, Op } from '@nocobase/database';
 | 
				
			||||||
import WorkflowModel from '../models/Workflow';
 | 
					import type { WorkflowModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function create(context: Context, next) {
 | 
					export async function create(context: Context, next) {
 | 
				
			||||||
  const { db } = context;
 | 
					  const { db } = context;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,5 @@
 | 
				
			|||||||
import Plugin from '..';
 | 
					import Plugin from '..';
 | 
				
			||||||
import ExecutionModel from '../models/Execution';
 | 
					import type { ExecutionModel, FlowNodeModel } from '../types';
 | 
				
			||||||
import FlowNodeModel from '../models/FlowNode';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type CustomFunction = (this: { execution: ExecutionModel; node?: FlowNodeModel }) => any;
 | 
					export type CustomFunction = (this: { execution: ExecutionModel; node?: FlowNodeModel }) => any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -3,3 +3,4 @@ export * from './constants';
 | 
				
			|||||||
export { Trigger } from './triggers';
 | 
					export { Trigger } from './triggers';
 | 
				
			||||||
export { default as Processor } from './Processor';
 | 
					export { default as Processor } from './Processor';
 | 
				
			||||||
export { default } from './Plugin';
 | 
					export { default } from './Plugin';
 | 
				
			||||||
 | 
					export * from './types';
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,8 @@
 | 
				
			|||||||
import { BelongsToManyRepository, DataTypes, HasManyRepository } from '@nocobase/database';
 | 
					import { BelongsToManyRepository, DataTypes, HasManyRepository } from '@nocobase/database';
 | 
				
			||||||
import { JOB_STATUS } from '../constants';
 | 
					
 | 
				
			||||||
import FlowNodeModel from '../models/FlowNode';
 | 
					 | 
				
			||||||
import Processor from '../Processor';
 | 
					import Processor from '../Processor';
 | 
				
			||||||
 | 
					import { JOB_STATUS } from '../constants';
 | 
				
			||||||
 | 
					import type { FlowNodeModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const aggregators = {
 | 
					const aggregators = {
 | 
				
			||||||
  count: 'count',
 | 
					  count: 'count',
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@ import { parse } from '@nocobase/utils';
 | 
				
			|||||||
import { Instruction } from '.';
 | 
					import { Instruction } from '.';
 | 
				
			||||||
import { Processor } from '..';
 | 
					import { Processor } from '..';
 | 
				
			||||||
import { JOB_STATUS } from '../constants';
 | 
					import { JOB_STATUS } from '../constants';
 | 
				
			||||||
import FlowNodeModel from '../models/FlowNode';
 | 
					import type { FlowNodeModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface CalculationConfig {
 | 
					interface CalculationConfig {
 | 
				
			||||||
  dynamic?: boolean | string;
 | 
					  dynamic?: boolean | string;
 | 
				
			||||||
 | 
				
			|||||||
@ -3,9 +3,11 @@ import { Registry } from '@nocobase/utils';
 | 
				
			|||||||
import { Instruction } from '.';
 | 
					import { Instruction } from '.';
 | 
				
			||||||
import { Processor } from '..';
 | 
					import { Processor } from '..';
 | 
				
			||||||
import { JOB_STATUS } from '../constants';
 | 
					import { JOB_STATUS } from '../constants';
 | 
				
			||||||
import FlowNodeModel from '../models/FlowNode';
 | 
					import type { FlowNodeModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const calculators = new Registry<Function>();
 | 
					type Comparer = (a: any, b: any) => boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const calculators = new Registry<Comparer>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// built-in functions
 | 
					// built-in functions
 | 
				
			||||||
function equal(a, b) {
 | 
					function equal(a, b) {
 | 
				
			||||||
@ -92,7 +94,9 @@ type CalculationGroup = {
 | 
				
			|||||||
type Calculation = CalculationItem | CalculationGroup;
 | 
					type Calculation = CalculationItem | CalculationGroup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function calculate(calculation: CalculationItem = {}) {
 | 
					function calculate(calculation: CalculationItem = {}) {
 | 
				
			||||||
  let fn: Function;
 | 
					  type NewType = Comparer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let fn: NewType;
 | 
				
			||||||
  if (!(calculation.calculator && (fn = calculators.get(calculation.calculator)))) {
 | 
					  if (!(calculation.calculator && (fn = calculators.get(calculation.calculator)))) {
 | 
				
			||||||
    throw new Error(`no calculator function registered for "${calculation.calculator}"`);
 | 
					    throw new Error(`no calculator function registered for "${calculation.calculator}"`);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import { JOB_STATUS } from '../constants';
 | 
					import { JOB_STATUS } from '../constants';
 | 
				
			||||||
import FlowNodeModel from '../models/FlowNode';
 | 
					import type { FlowNodeModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  async run(node: FlowNodeModel, input, processor) {
 | 
					  async run(node: FlowNodeModel, input, processor) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,8 @@
 | 
				
			|||||||
import Plugin from '..';
 | 
					import Plugin from '..';
 | 
				
			||||||
import { EXECUTION_STATUS, JOB_STATUS } from '../constants';
 | 
					import { EXECUTION_STATUS, JOB_STATUS } from '../constants';
 | 
				
			||||||
import ExecutionModel from '../models/Execution';
 | 
					 | 
				
			||||||
import JobModel from '../models/Job';
 | 
					 | 
				
			||||||
import Processor from '../Processor';
 | 
					import Processor from '../Processor';
 | 
				
			||||||
import { Instruction } from '.';
 | 
					import { Instruction } from '.';
 | 
				
			||||||
 | 
					import type { ExecutionModel, JobModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ValueOf<T> = T[keyof T];
 | 
					type ValueOf<T> = T[keyof T];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import { JOB_STATUS } from '../constants';
 | 
					import { JOB_STATUS } from '../constants';
 | 
				
			||||||
import FlowNodeModel from '../models/FlowNode';
 | 
					import type { FlowNodeModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  async run(node: FlowNodeModel, input, processor) {
 | 
					  async run(node: FlowNodeModel, input, processor) {
 | 
				
			||||||
 | 
				
			|||||||
@ -2,11 +2,11 @@ import path from 'path';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { requireModule } from '@nocobase/utils';
 | 
					import { requireModule } from '@nocobase/utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import FlowNodeModel from '../models/FlowNode';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import Plugin from '..';
 | 
					import Plugin from '..';
 | 
				
			||||||
import Processor from '../Processor';
 | 
					import Processor from '../Processor';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import type { FlowNodeModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Job = {
 | 
					export type Job = {
 | 
				
			||||||
  status: number;
 | 
					  status: number;
 | 
				
			||||||
  result?: unknown;
 | 
					  result?: unknown;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,6 @@
 | 
				
			|||||||
import FlowNodeModel from '../models/FlowNode';
 | 
					 | 
				
			||||||
import JobModel from '../models/Job';
 | 
					 | 
				
			||||||
import Processor from '../Processor';
 | 
					import Processor from '../Processor';
 | 
				
			||||||
import { JOB_STATUS } from '../constants';
 | 
					import { JOB_STATUS } from '../constants';
 | 
				
			||||||
 | 
					import type { FlowNodeModel, JobModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getTargetLength(target) {
 | 
					function getTargetLength(target) {
 | 
				
			||||||
  let length = 0;
 | 
					  let length = 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,6 @@
 | 
				
			|||||||
import FlowNodeModel from '../models/FlowNode';
 | 
					 | 
				
			||||||
import JobModel from '../models/Job';
 | 
					 | 
				
			||||||
import Processor from '../Processor';
 | 
					import Processor from '../Processor';
 | 
				
			||||||
import { JOB_STATUS } from '../constants';
 | 
					import { JOB_STATUS } from '../constants';
 | 
				
			||||||
 | 
					import type { FlowNodeModel, JobModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const PARALLEL_MODE = {
 | 
					export const PARALLEL_MODE = {
 | 
				
			||||||
  ALL: 'all',
 | 
					  ALL: 'all',
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
import FlowNodeModel from '../models/FlowNode';
 | 
					 | 
				
			||||||
import Processor from '../Processor';
 | 
					import Processor from '../Processor';
 | 
				
			||||||
import { JOB_STATUS } from '../constants';
 | 
					import { JOB_STATUS } from '../constants';
 | 
				
			||||||
 | 
					import type { FlowNodeModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  async run(node: FlowNodeModel, input, processor: Processor) {
 | 
					  async run(node: FlowNodeModel, input, processor: Processor) {
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@ import axios, { AxiosRequestConfig } from 'axios';
 | 
				
			|||||||
import { Instruction } from './index';
 | 
					import { Instruction } from './index';
 | 
				
			||||||
import { JOB_STATUS } from '../constants';
 | 
					import { JOB_STATUS } from '../constants';
 | 
				
			||||||
import Processor from '../Processor';
 | 
					import Processor from '../Processor';
 | 
				
			||||||
import FlowNodeModel from '../models/FlowNode';
 | 
					import type { FlowNodeModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface Header {
 | 
					export interface Header {
 | 
				
			||||||
  name: string;
 | 
					  name: string;
 | 
				
			||||||
@ -53,6 +53,7 @@ export default class implements Instruction {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const config = processor.getParsedValue(node.config, node) as RequestConfig;
 | 
					    const config = processor.getParsedValue(node.config, node) as RequestConfig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // eslint-disable-next-line promise/catch-or-return
 | 
				
			||||||
    request(config)
 | 
					    request(config)
 | 
				
			||||||
      .then((response) => {
 | 
					      .then((response) => {
 | 
				
			||||||
        job.set({
 | 
					        job.set({
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
import FlowNodeModel from '../models/FlowNode';
 | 
					 | 
				
			||||||
import Processor from '../Processor';
 | 
					import Processor from '../Processor';
 | 
				
			||||||
import { JOB_STATUS } from '../constants';
 | 
					import { JOB_STATUS } from '../constants';
 | 
				
			||||||
 | 
					import type { FlowNodeModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  async run(node: FlowNodeModel, input, processor: Processor) {
 | 
					  async run(node: FlowNodeModel, input, processor: Processor) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
import { Collection, Model } from '@nocobase/database';
 | 
					import { Collection, Model } from '@nocobase/database';
 | 
				
			||||||
import { Trigger } from '..';
 | 
					import { Trigger } from '..';
 | 
				
			||||||
import WorkflowModel from '../models/Workflow';
 | 
					import type { WorkflowModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface CollectionChangeTriggerConfig {
 | 
					export interface CollectionChangeTriggerConfig {
 | 
				
			||||||
  collection: string;
 | 
					  collection: string;
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@ import path from 'path';
 | 
				
			|||||||
import { requireModule } from '@nocobase/utils';
 | 
					import { requireModule } from '@nocobase/utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Plugin from '..';
 | 
					import Plugin from '..';
 | 
				
			||||||
import WorkflowModel from '../models/Workflow';
 | 
					import type { WorkflowModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export abstract class Trigger {
 | 
					export abstract class Trigger {
 | 
				
			||||||
  constructor(public readonly plugin: Plugin) {}
 | 
					  constructor(public readonly plugin: Plugin) {}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
import { fn, literal, Op, where } from '@nocobase/database';
 | 
					import { fn, literal, Op, where } from '@nocobase/database';
 | 
				
			||||||
import parser from 'cron-parser';
 | 
					import parser from 'cron-parser';
 | 
				
			||||||
import Plugin, { Trigger } from '..';
 | 
					import Plugin, { Trigger } from '..';
 | 
				
			||||||
import WorkflowModel from '../models/Workflow';
 | 
					import type { WorkflowModel } from '../types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type ScheduleOnField =
 | 
					export type ScheduleOnField =
 | 
				
			||||||
  | string
 | 
					  | string
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										4
									
								
								packages/plugins/workflow/src/server/types/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/plugins/workflow/src/server/types/index.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					export type { default as WorkflowModel } from './Workflow';
 | 
				
			||||||
 | 
					export type { default as FlowNodeModel } from './FlowNode';
 | 
				
			||||||
 | 
					export type { default as ExecutionModel } from './Execution';
 | 
				
			||||||
 | 
					export type { default as JobModel } from './Job';
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user