import dayjs from 'dayjs'; import { RulesLogic } from 'json-logic-js'; import { Element } from '../models/element'; import type { ApiResponse } from '../services/api/apisauce'; import { Prettify } from '../util/prettify'; import { AttributeValue, ElementDataWrapper } from './element.interface'; import { TemplateButton } from './templateButton.interface'; export type DateFormat = string | dayjs.Dayjs | Date; export interface OnElementCriteria { collection: string | string[]; type: 'relation' | 'reference'; criteria: Prettify; } export type ExistsCriterium = { $exists: boolean; }; export type NotEqualCriterium = { $ne: T; }; export type NotCriterium = { $not: T; }; export type Criterium = AttributeValue | DateQuery | LocationQuery | InQuery | ExistsCriterium | OnElementCriteria | NotEqualCriterium | NotCriterium; export type RawCriterium = DateQuery | LocationQuery | InQueryFormatted | ExistsCriterium | OnElementCriteria | NotEqualCriterium | NotCriterium | string | number; export type CriteriumKey = `${string}.value` | `${string}.file` | 'organization' | 'timestamp' | 'hash' | 'updatedAt' | 'updatedBy' | '$or'; export type ComparisonOperators = { $gt?: T; $gte?: T; $lt?: T; $lte?: T; }; export type DateQuery = ComparisonOperators; type NumberComparison = number | ComparisonOperators; export type FileAttributeCriteria = { filename?: string; file_size?: NumberComparison; hash?: string; created_at?: DateQuery; relevant?: boolean; archived?: boolean; }; export type FileCriteria = { [K in `${string}.file`]?: FileAttributeCriteria; }; export type ValueCriteria = { [K in `${string}.value`]?: T; }; export type MetaAttributeKey = 'organization' | 'timestamp' | 'hash' | 'updatedAt' | 'updatedBy'; export type MetaCriteria = { [K in MetaAttributeKey]?: K extends 'organization' ? string : T; }; export type AllowedBareKey = Exclude, `${string}.file` | `${string}.value` | MetaAttributeKey | '$or'>; type RawCriteriaBase = Prettify & FileCriteria & MetaCriteria>>; type RawCriteriaStrict = RawCriteriaBase & { $or?: RawCriteria[]; }; type RawCriteriaLoose = { [K in string & NonNullable]?: unknown; }; export type RawCriteria = RawCriteriaLoose | RawCriteriaStrict; export type BareValueCriteria = Partial>; type QueryCriteriaStrict = Prettify & ValueCriteria & MetaCriteria> & { $or?: QueryCriteria[]; }>; type QueryCriteriaLoose = { [K in string & NonNullable]?: unknown; }; export type QueryCriteria = QueryCriteriaLoose | QueryCriteriaStrict; export interface ListingQuery { collection: string | string[] | null; criteria: QueryCriteria; projection: Record; element?: Record; paginate?: { 'per-page': number; page: number; }; sort: Record; atTime?: string; preventDefaultArchive?: boolean; } export interface RawListingQuery { collection?: string | string[] | null; criteria: RawCriteria; projection: Record; paginate?: IQueryOptions['paginate']; sort?: IQueryOptions['sort']; groups?: boolean; atTime?: string; preventDefaultArchive?: boolean; } export type ExtendedListingValue = { cardCommentsModal?: boolean; cardGridColumns?: number; query: IListingConfig; selectionActions?: TemplateButton[]; }; export interface ListingRequestData { query: RawListingQuery; element: Record; } export type SortCriteria = Record; export type LocationQuery = { $near: { $geometry: { type: string; coordinates: [number, number]; }; $maxDistance: number; }; }; export type InQuery = { $in: AttributeValue[]; }; export type InQueryFormatted = { $in: string[]; }; interface QrLabelsBase { qrSourceAttr: string; attrPositions: string[]; showAttrNames: boolean; includeElementType?: boolean; } export interface QRLabels extends QrLabelsBase { includeCurrentElements: QrLabelsBase; } export interface IListingConfig { displayName?: string; name?: string; disabledCriteria?: string[]; staticElementTypes?: boolean; cardView?: boolean; cardAttributeColumns?: boolean; displayMode?: 'table' | 'map' | 'calendar'; sumRow?: boolean; hideAttributes?: string[]; highlightCriteria?: string[]; columnWidths?: Record; attributesInEditMode?: string[]; qrLabels?: QRLabels; tags?: string[]; type: string | string[] | null; criteria: QueryCriteria; projection: string[]; sort?: SortCriteria | SortCriteria[]; page?: number; limit?: number; localSort?: (results: Element[]) => Promise; localSortByDistance?: boolean; localSortByElementDistance?: Element; atTime?: string; preventDefaultArchive?: boolean; } export type ListingHeaders = { 'x-allow-async-listing'?: 'true' | 'false'; 'x-sync-children'?: 'true' | 'false'; }; export type ListingOptions = { allowAsyncListing?: boolean; syncChildren?: boolean; }; export type ListingGet = (type: string | string[] | null, criteria: RawCriteria, projection: string[], sort?: Record, page?: number, limit?: number, atTime?: string, queryParams?: Record, options?: ListingOptions, preventDefaultArchive?: boolean) => Promise>; export interface ListingService { get: ListingGet; } export type SerializableListingParams = Parameters; export type ParsedListingConfig = Omit & { criteria: RawCriteria; } & { type: string[] | null; parsed: true; }; export interface ParsedListingParams { params: SerializableListingParams; dataHash: string; parsedConfig: ParsedListingConfig; tags?: string[]; } export interface ListingLogicConfig { logic: RulesLogic; type: string[]; } export interface IListingFilter { key: string; type?: string; value: string | number | DateQuery | IDateGteCriterion | IDateLtCriterion | IDateLteCriterion | ILocationCriterion | { $ne: string; } | { $near: Record; } | IOnElementQuery | null | string[]; filterBlock?: number; logicOperation?: 'EQUAL' | 'NOTEQUAL' | 'IN' | 'NOTIN' | '≥' | '>' | '<' | '≤' | 'CONTAINSWORD'; } export interface ILocationData { location: { lat: number; lng: number; } | null; radius: number; } export interface IOnElementQuery { collection: string; type: 'relation' | 'reference'; criteria?: { [key: string]: IListingFilter['value']; } & { $or?: IOnElementQuery['criteria'][]; }; } export interface IListingPreset { type: string | string[] | null; showInGraph?: string[]; sortBy?: string; sortReverse?: 1 | -1; filter?: (IListingFilter | IListingFilter[])[]; relationFilters?: CombinedCriteria['onElementCriteria']; recordFilters?: IListingRecordFilter[]; pagination?: { page: number; limit: number; }; locationData?: ILocationData; showGraph?: boolean; showTable?: boolean; filterCollapsed?: boolean; showArchived?: boolean; countNumberAttributes?: boolean; } interface IListingRecordFilter { due_date: string; actions: string; name: string; author: string; } export interface CombinedCriteria { basicCriteria: IListingFilter[]; onElementCriteria?: { collection: string; attribute: string; criteria?: IListingFilter[]; type?: 'relation' | 'reference'; }; } interface ILocationCriterion { $near: { $geometry: { type: 'Point'; coordinates: [number, number]; }; $maxDistance: number; }; } export interface IDateGteCriterion { $gte: string | Date; } export interface IDateLtCriterion { $lt: string | Date; } export interface IDateLteCriterion { $lte: string | Date; } export interface IListingElementsResponse { elements: T[]; count: number; asyncListingInitiated?: boolean; } export interface IQueryOptions { paginate: { page: number; 'per-page': number; }; showArchived?: boolean; sort: { [key: string]: 1 | -1; }; atTime?: string; } export {};