mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-07 08:03:09 +00:00
fix(ui): types reference issue (#12789)
* fix(ui): types reference issue * fix: code smells
This commit is contained in:
parent
d4ed941371
commit
30dbfb8458
@ -38,16 +38,14 @@ import {
|
|||||||
PipelineType,
|
PipelineType,
|
||||||
} from '../../generated/api/services/ingestionPipelines/createIngestionPipeline';
|
} from '../../generated/api/services/ingestionPipelines/createIngestionPipeline';
|
||||||
import {
|
import {
|
||||||
ConfigClass,
|
|
||||||
ConfigType,
|
ConfigType,
|
||||||
FilterPattern,
|
FilterPattern,
|
||||||
IngestionPipeline,
|
IngestionPipeline,
|
||||||
|
Pipeline,
|
||||||
} from '../../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
} from '../../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
||||||
import { ProfileSampleType } from '../../generated/metadataIngestion/databaseServiceProfilerPipeline';
|
import { ProfileSampleType } from '../../generated/metadataIngestion/databaseServiceProfilerPipeline';
|
||||||
import {
|
|
||||||
DbtConfig,
|
import { DbtPipeline } from 'generated/metadataIngestion/dbtPipeline';
|
||||||
DbtPipelineClass,
|
|
||||||
} from '../../generated/metadataIngestion/dbtPipeline';
|
|
||||||
import {
|
import {
|
||||||
getCurrentUserId,
|
getCurrentUserId,
|
||||||
getFilterTypes,
|
getFilterTypes,
|
||||||
@ -65,7 +63,7 @@ import DeployIngestionLoaderModal from '../Modals/DeployIngestionLoaderModal/Dep
|
|||||||
import {
|
import {
|
||||||
AddIngestionProps,
|
AddIngestionProps,
|
||||||
AddIngestionState,
|
AddIngestionState,
|
||||||
ModifiedDbtConfig,
|
ModifiedDBTConfigurationSource,
|
||||||
} from './addIngestion.interface';
|
} from './addIngestion.interface';
|
||||||
import ConfigureIngestion from './Steps/ConfigureIngestion';
|
import ConfigureIngestion from './Steps/ConfigureIngestion';
|
||||||
import DataInsightMetadataToESConfigForm from './Steps/DataInsightMetadataToESConfigForm/DataInsightMetadataToESConfigForm';
|
import DataInsightMetadataToESConfigForm from './Steps/DataInsightMetadataToESConfigForm/DataInsightMetadataToESConfigForm';
|
||||||
@ -98,8 +96,8 @@ const AddIngestion = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { sourceConfig, sourceConfigType } = useMemo(
|
const { sourceConfig, sourceConfigType } = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
sourceConfig: data?.sourceConfig.config as ConfigClass,
|
sourceConfig: data?.sourceConfig.config as Pipeline,
|
||||||
sourceConfigType: (data?.sourceConfig.config as ConfigClass)?.type,
|
sourceConfigType: (data?.sourceConfig.config as Pipeline)?.type,
|
||||||
}),
|
}),
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
@ -129,8 +127,7 @@ const AddIngestion = ({
|
|||||||
profilerIngestionType,
|
profilerIngestionType,
|
||||||
} = useMemo(() => {
|
} = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
configData: (data?.sourceConfig.config as DbtPipelineClass)
|
configData: (data?.sourceConfig.config as DbtPipeline)?.dbtConfigSource,
|
||||||
?.dbtConfigSource,
|
|
||||||
usageIngestionType: sourceConfigType ?? ConfigType.DatabaseUsage,
|
usageIngestionType: sourceConfigType ?? ConfigType.DatabaseUsage,
|
||||||
lineageIngestionType: sourceConfigType ?? ConfigType.DatabaseLineage,
|
lineageIngestionType: sourceConfigType ?? ConfigType.DatabaseLineage,
|
||||||
profilerIngestionType: sourceConfigType ?? ConfigType.Profiler,
|
profilerIngestionType: sourceConfigType ?? ConfigType.Profiler,
|
||||||
@ -150,7 +147,7 @@ const AddIngestion = ({
|
|||||||
}, [isDatabaseService, pipelineType]);
|
}, [isDatabaseService, pipelineType]);
|
||||||
|
|
||||||
const sourceTypeData = useMemo(
|
const sourceTypeData = useMemo(
|
||||||
() => getSourceTypeFromConfig(configData as DbtConfig | undefined),
|
() => getSourceTypeFromConfig(configData),
|
||||||
[configData]
|
[configData]
|
||||||
);
|
);
|
||||||
const { database, ingestAllDatabases } = serviceData.connection
|
const { database, ingestAllDatabases } = serviceData.connection
|
||||||
@ -186,7 +183,7 @@ const AddIngestion = ({
|
|||||||
showPipelineFilter: !isUndefined(sourceConfig?.pipelineFilterPattern),
|
showPipelineFilter: !isUndefined(sourceConfig?.pipelineFilterPattern),
|
||||||
showMlModelFilter: !isUndefined(sourceConfig?.mlModelFilterPattern),
|
showMlModelFilter: !isUndefined(sourceConfig?.mlModelFilterPattern),
|
||||||
showContainerFilter: !isUndefined(sourceConfig?.containerFilterPattern),
|
showContainerFilter: !isUndefined(sourceConfig?.containerFilterPattern),
|
||||||
dbtConfigSource: configData as ModifiedDbtConfig,
|
dbtConfigSource: configData as ModifiedDBTConfigurationSource,
|
||||||
gcsConfigType: showDBTConfig ? sourceTypeData.gcsType : undefined,
|
gcsConfigType: showDBTConfig ? sourceTypeData.gcsType : undefined,
|
||||||
chartFilterPattern:
|
chartFilterPattern:
|
||||||
sourceConfig?.chartFilterPattern ?? INITIAL_FILTER_PATTERN,
|
sourceConfig?.chartFilterPattern ?? INITIAL_FILTER_PATTERN,
|
||||||
@ -277,7 +274,7 @@ const AddIngestion = ({
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleMetadataToESConfig = (data: ConfigClass) => {
|
const handleMetadataToESConfig = (data: Pipeline) => {
|
||||||
handleStateChange({
|
handleStateChange({
|
||||||
metadataToESConfig: data,
|
metadataToESConfig: data,
|
||||||
});
|
});
|
||||||
@ -501,7 +498,7 @@ const AddIngestion = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getConfigData = (type: PipelineType): ConfigClass => {
|
const getConfigData = (type: PipelineType): Pipeline => {
|
||||||
const {
|
const {
|
||||||
databaseFilterPattern,
|
databaseFilterPattern,
|
||||||
dbtConfigSource,
|
dbtConfigSource,
|
||||||
@ -577,7 +574,7 @@ const AddIngestion = ({
|
|||||||
'dbtClassificationName',
|
'dbtClassificationName',
|
||||||
'includeTags',
|
'includeTags',
|
||||||
]),
|
]),
|
||||||
} as ConfigClass),
|
} as Pipeline),
|
||||||
type: ConfigType.Dbt,
|
type: ConfigType.Dbt,
|
||||||
dbtUpdateDescriptions: dbtConfigSource?.dbtUpdateDescriptions,
|
dbtUpdateDescriptions: dbtConfigSource?.dbtUpdateDescriptions,
|
||||||
includeTags: dbtConfigSource?.includeTags,
|
includeTags: dbtConfigSource?.includeTags,
|
||||||
@ -673,7 +670,7 @@ const AddIngestion = ({
|
|||||||
loggerLevel: enableDebugLog ? LogLevels.Debug : LogLevels.Info,
|
loggerLevel: enableDebugLog ? LogLevels.Debug : LogLevels.Info,
|
||||||
sourceConfig: {
|
sourceConfig: {
|
||||||
config: {
|
config: {
|
||||||
...(data.sourceConfig.config as ConfigClass),
|
...(data.sourceConfig.config as Pipeline),
|
||||||
...getConfigData(pipelineType),
|
...getConfigData(pipelineType),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -15,12 +15,12 @@ import { Button, Col, Divider, Form, Input, Row, Switch } from 'antd';
|
|||||||
import { AddIngestionState } from 'components/AddIngestion/addIngestion.interface';
|
import { AddIngestionState } from 'components/AddIngestion/addIngestion.interface';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ConfigClass } from '../../../../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
import { Pipeline } from '../../../../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
||||||
import '../MetadataToESConfigForm/MetadataToESConfigForm.less';
|
import '../MetadataToESConfigForm/MetadataToESConfigForm.less';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data: AddIngestionState;
|
data: AddIngestionState;
|
||||||
handleMetadataToESConfig: (data: ConfigClass) => void;
|
handleMetadataToESConfig: (data: Pipeline) => void;
|
||||||
handlePrev: () => void;
|
handlePrev: () => void;
|
||||||
handleNext: () => void;
|
handleNext: () => void;
|
||||||
onFocus: (fieldId: string) => void;
|
onFocus: (fieldId: string) => void;
|
||||||
@ -38,7 +38,7 @@ const DataInsightMetadataToESConfigForm = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
const handleSubmit = (values: ConfigClass) => {
|
const handleSubmit = (values: Pipeline) => {
|
||||||
handleMetadataToESConfig({
|
handleMetadataToESConfig({
|
||||||
...values,
|
...values,
|
||||||
});
|
});
|
||||||
|
@ -20,12 +20,12 @@ import {
|
|||||||
} from 'constants/elasticsearch.constant';
|
} from 'constants/elasticsearch.constant';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ConfigClass } from '../../../../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
import { Pipeline } from '../../../../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
||||||
import './MetadataToESConfigForm.less';
|
import './MetadataToESConfigForm.less';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data: AddIngestionState;
|
data: AddIngestionState;
|
||||||
handleMetadataToESConfig: (data: ConfigClass) => void;
|
handleMetadataToESConfig: (data: Pipeline) => void;
|
||||||
handlePrev: () => void;
|
handlePrev: () => void;
|
||||||
handleNext: () => void;
|
handleNext: () => void;
|
||||||
onFocus: (fieldId: string) => void;
|
onFocus: (fieldId: string) => void;
|
||||||
@ -43,7 +43,7 @@ const MetadataToESConfigForm = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
const handleSubmit = (values: ConfigClass) => {
|
const handleSubmit = (values: Pipeline) => {
|
||||||
handleMetadataToESConfig({
|
handleMetadataToESConfig({
|
||||||
...values,
|
...values,
|
||||||
});
|
});
|
||||||
|
@ -11,14 +11,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { DbtPipeline } from 'generated/metadataIngestion/dbtPipeline';
|
||||||
import { LoadingState, ServicesUpdateRequest } from 'Models';
|
import { LoadingState, ServicesUpdateRequest } from 'Models';
|
||||||
import { FilterPatternEnum } from '../../enums/filterPattern.enum';
|
import { FilterPatternEnum } from '../../enums/filterPattern.enum';
|
||||||
import { FormSubmitType } from '../../enums/form.enum';
|
import { FormSubmitType } from '../../enums/form.enum';
|
||||||
import { ServiceCategory } from '../../enums/service.enum';
|
import { ServiceCategory } from '../../enums/service.enum';
|
||||||
import {
|
import {
|
||||||
ConfigClass,
|
|
||||||
CreateIngestionPipeline,
|
CreateIngestionPipeline,
|
||||||
DbtConfig,
|
DBTConfigurationSource,
|
||||||
|
Pipeline,
|
||||||
} from '../../generated/api/services/ingestionPipelines/createIngestionPipeline';
|
} from '../../generated/api/services/ingestionPipelines/createIngestionPipeline';
|
||||||
import { ProfileSampleType } from '../../generated/entity/data/table';
|
import { ProfileSampleType } from '../../generated/entity/data/table';
|
||||||
import {
|
import {
|
||||||
@ -26,7 +27,6 @@ import {
|
|||||||
IngestionPipeline,
|
IngestionPipeline,
|
||||||
PipelineType,
|
PipelineType,
|
||||||
} from '../../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
} from '../../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
||||||
import { DbtPipelineClass } from '../../generated/metadataIngestion/dbtPipeline';
|
|
||||||
import {
|
import {
|
||||||
DBT_SOURCES,
|
DBT_SOURCES,
|
||||||
GCS_CONFIG,
|
GCS_CONFIG,
|
||||||
@ -88,9 +88,9 @@ export type ScheduleIntervalProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Todo: Need to refactor below type, as per schema change #9575
|
// Todo: Need to refactor below type, as per schema change #9575
|
||||||
export type ModifiedDbtConfig = DbtConfig &
|
export type ModifiedDBTConfigurationSource = DBTConfigurationSource &
|
||||||
Pick<
|
Pick<
|
||||||
DbtPipelineClass,
|
DbtPipeline,
|
||||||
| 'dbtUpdateDescriptions'
|
| 'dbtUpdateDescriptions'
|
||||||
| 'dbtClassificationName'
|
| 'dbtClassificationName'
|
||||||
| 'includeTags'
|
| 'includeTags'
|
||||||
@ -110,7 +110,7 @@ export interface AddIngestionState {
|
|||||||
databaseServiceNames: string[];
|
databaseServiceNames: string[];
|
||||||
dbtClassificationName: string;
|
dbtClassificationName: string;
|
||||||
dbtUpdateDescriptions: boolean;
|
dbtUpdateDescriptions: boolean;
|
||||||
dbtConfigSource: ModifiedDbtConfig;
|
dbtConfigSource: ModifiedDBTConfigurationSource;
|
||||||
dbtConfigSourceType: DBT_SOURCES;
|
dbtConfigSourceType: DBT_SOURCES;
|
||||||
description: string;
|
description: string;
|
||||||
enableDebugLog: boolean;
|
enableDebugLog: boolean;
|
||||||
@ -128,7 +128,7 @@ export interface AddIngestionState {
|
|||||||
markDeletedTopics?: boolean;
|
markDeletedTopics?: boolean;
|
||||||
markDeletedMlModels?: boolean;
|
markDeletedMlModels?: boolean;
|
||||||
markDeletedPipelines?: boolean;
|
markDeletedPipelines?: boolean;
|
||||||
metadataToESConfig: ConfigClass | undefined;
|
metadataToESConfig: Pipeline | undefined;
|
||||||
mlModelFilterPattern: FilterPattern;
|
mlModelFilterPattern: FilterPattern;
|
||||||
pipelineFilterPattern: FilterPattern;
|
pipelineFilterPattern: FilterPattern;
|
||||||
profileSample: number | undefined;
|
profileSample: number | undefined;
|
||||||
|
@ -15,12 +15,12 @@ import { FilterPatternEnum } from 'enums/filterPattern.enum';
|
|||||||
import { FormSubmitType } from '../../../enums/form.enum';
|
import { FormSubmitType } from '../../../enums/form.enum';
|
||||||
import {
|
import {
|
||||||
Credentials,
|
Credentials,
|
||||||
DbtConfig,
|
DBTConfigurationSource,
|
||||||
GCPCredentialsValues,
|
GCPCredentialsValues,
|
||||||
} from '../../../generated/metadataIngestion/dbtPipeline';
|
} from '../../../generated/metadataIngestion/dbtPipeline';
|
||||||
import {
|
import {
|
||||||
AddIngestionState,
|
AddIngestionState,
|
||||||
ModifiedDbtConfig,
|
ModifiedDBTConfigurationSource,
|
||||||
} from '../../AddIngestion/addIngestion.interface';
|
} from '../../AddIngestion/addIngestion.interface';
|
||||||
import { DBT_SOURCES, GCS_CONFIG } from './DBTFormEnum';
|
import { DBT_SOURCES, GCS_CONFIG } from './DBTFormEnum';
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ export interface DBTFormCommonProps {
|
|||||||
okText: string;
|
okText: string;
|
||||||
cancelText: string;
|
cancelText: string;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
onSubmit: (data?: DbtConfig) => void;
|
onSubmit: (data?: DBTConfigurationSource) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DBTConfigFormProps extends DBTFormCommonProps {
|
export interface DBTConfigFormProps extends DBTFormCommonProps {
|
||||||
@ -42,7 +42,7 @@ export interface DBTConfigFormProps extends DBTFormCommonProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type DbtConfigCloud = Pick<
|
export type DbtConfigCloud = Pick<
|
||||||
ModifiedDbtConfig,
|
ModifiedDBTConfigurationSource,
|
||||||
| 'dbtCloudAccountId'
|
| 'dbtCloudAccountId'
|
||||||
| 'dbtCloudAuthToken'
|
| 'dbtCloudAuthToken'
|
||||||
| 'dbtUpdateDescriptions'
|
| 'dbtUpdateDescriptions'
|
||||||
@ -54,7 +54,7 @@ export type DbtConfigCloud = Pick<
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
export type DbtConfigLocal = Pick<
|
export type DbtConfigLocal = Pick<
|
||||||
ModifiedDbtConfig,
|
ModifiedDBTConfigurationSource,
|
||||||
| 'dbtCatalogFilePath'
|
| 'dbtCatalogFilePath'
|
||||||
| 'dbtManifestFilePath'
|
| 'dbtManifestFilePath'
|
||||||
| 'dbtRunResultsFilePath'
|
| 'dbtRunResultsFilePath'
|
||||||
@ -64,7 +64,7 @@ export type DbtConfigLocal = Pick<
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
export type DbtConfigHttp = Pick<
|
export type DbtConfigHttp = Pick<
|
||||||
ModifiedDbtConfig,
|
ModifiedDBTConfigurationSource,
|
||||||
| 'dbtCatalogHttpPath'
|
| 'dbtCatalogHttpPath'
|
||||||
| 'dbtManifestHttpPath'
|
| 'dbtManifestHttpPath'
|
||||||
| 'dbtRunResultsHttpPath'
|
| 'dbtRunResultsHttpPath'
|
||||||
@ -74,7 +74,7 @@ export type DbtConfigHttp = Pick<
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
export type DbtConfigS3GCS = Pick<
|
export type DbtConfigS3GCS = Pick<
|
||||||
ModifiedDbtConfig,
|
ModifiedDBTConfigurationSource,
|
||||||
| 'dbtSecurityConfig'
|
| 'dbtSecurityConfig'
|
||||||
| 'dbtPrefixConfig'
|
| 'dbtPrefixConfig'
|
||||||
| 'dbtUpdateDescriptions'
|
| 'dbtUpdateDescriptions'
|
||||||
@ -83,7 +83,7 @@ export type DbtConfigS3GCS = Pick<
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
export type DbtConfigAzure = Pick<
|
export type DbtConfigAzure = Pick<
|
||||||
ModifiedDbtConfig,
|
ModifiedDBTConfigurationSource,
|
||||||
| 'dbtSecurityConfig'
|
| 'dbtSecurityConfig'
|
||||||
| 'dbtPrefixConfig'
|
| 'dbtPrefixConfig'
|
||||||
| 'dbtUpdateDescriptions'
|
| 'dbtUpdateDescriptions'
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ModifiedDbtConfig } from 'components/AddIngestion/addIngestion.interface';
|
import { ModifiedDBTConfigurationSource } from 'components/AddIngestion/addIngestion.interface';
|
||||||
import {
|
import {
|
||||||
DbtConfigCloud,
|
DbtConfigCloud,
|
||||||
DbtConfigHttp,
|
DbtConfigHttp,
|
||||||
@ -30,7 +30,7 @@ import {
|
|||||||
import { isEmpty, isNil, isString } from 'lodash';
|
import { isEmpty, isNil, isString } from 'lodash';
|
||||||
|
|
||||||
export const getSourceTypeFromConfig = (
|
export const getSourceTypeFromConfig = (
|
||||||
data?: ModifiedDbtConfig,
|
data?: ModifiedDBTConfigurationSource,
|
||||||
defaultSource = DBT_SOURCES.local
|
defaultSource = DBT_SOURCES.local
|
||||||
): DbtSourceTypes => {
|
): DbtSourceTypes => {
|
||||||
let sourceType = defaultSource;
|
let sourceType = defaultSource;
|
||||||
|
@ -15,7 +15,7 @@ import { TableProfilerTab } from 'components/ProfilerDashboard/profilerDashboard
|
|||||||
import { getTableTabPath } from 'constants/constants';
|
import { getTableTabPath } from 'constants/constants';
|
||||||
import { OPEN_METADATA } from 'constants/service-guide.constant';
|
import { OPEN_METADATA } from 'constants/service-guide.constant';
|
||||||
import { EntityTabs } from 'enums/entity.enum';
|
import { EntityTabs } from 'enums/entity.enum';
|
||||||
import { ConfigClass } from 'generated/api/services/ingestionPipelines/createIngestionPipeline';
|
import { Pipeline } from 'generated/api/services/ingestionPipelines/createIngestionPipeline';
|
||||||
import { isUndefined, startCase } from 'lodash';
|
import { isUndefined, startCase } from 'lodash';
|
||||||
import { DataQualityPageTabs } from 'pages/DataQuality/DataQualityPage.interface';
|
import { DataQualityPageTabs } from 'pages/DataQuality/DataQualityPage.interface';
|
||||||
import { IngestionPipeline } from '../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
import { IngestionPipeline } from '../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
||||||
@ -71,7 +71,7 @@ export const getLogBreadCrumbs = (
|
|||||||
url:
|
url:
|
||||||
getTableTabPath(
|
getTableTabPath(
|
||||||
getEncodedFqn(
|
getEncodedFqn(
|
||||||
(ingestionDetails.sourceConfig.config as ConfigClass)
|
(ingestionDetails.sourceConfig.config as Pipeline)
|
||||||
?.entityFullyQualifiedName ?? ''
|
?.entityFullyQualifiedName ?? ''
|
||||||
),
|
),
|
||||||
EntityTabs.PROFILER
|
EntityTabs.PROFILER
|
||||||
|
Loading…
x
Reference in New Issue
Block a user