Skip to content

Commit f2fc0fe

Browse files
committed
Add type and api resolvers
1 parent dcafcae commit f2fc0fe

File tree

3 files changed

+64
-8
lines changed

3 files changed

+64
-8
lines changed

src/components/AutoQueryGrid.vue

+10-3
Original file line numberDiff line numberDiff line change
@@ -486,21 +486,28 @@ async function refresh() {
486486
await update()
487487
}
488488
489+
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent)
489490
async function search(args:any) {
490491
const op = apis.value.AnyQuery
491492
if (!op) {
492493
console.error(Errors.NoQuery)
493494
return
494495
}
495496
let requestDto = createDto(op, args)
497+
498+
let r = await client.api(requestDto)
496499
let complete = delaySet(x => {
497500
api.value.response = api.value.error = undefined
498501
apiLoading.value = x
502+
if (!isIOS) {
503+
api.value = r
504+
} else {
505+
// Fix for iOS which doesn't pick up reactive update on initial onload
506+
nextTick(() => api.value = r)
507+
}
499508
})
500-
let r = await client.api(requestDto)
501509
complete()
502-
// Fix for iOS which doesn't pick up reactive update on initial onload
503-
nextTick(() => api.value = r)
510+
504511
let results = mapGet(r.response as any,'results') || []
505512
if (!r.succeeded || results.label == 0) return
506513
// Forms.fetchLookupValues(results, this.columns, () => this.refreshResults())

src/types.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,24 @@ export interface UiConfig {
105105
navigate?: (url:string) => void
106106
assetsPathResolver?: (src:string) => string
107107
fallbackPathResolver?: (src:string) => string
108+
apisResolver?:(type:string|null, metaTypes?:MetadataTypes|null) => AutoQueryApis|null
109+
apiResolver?:(name:string) => MetadataOperationType|null
110+
typeResolver?:(name:string,namespace?:string|null) => MetadataType|null
108111
autoQueryGridDefaults?: AutoQueryGridDefaults
109112
storage?:Storage
110113
tableIcon?:ImageInfo
111114
scopeWhitelist?: {[k:string]:Function}
112115
}
113116

117+
export interface AutoQueryApis {
118+
Query?: MetadataOperationType;
119+
QueryInto?: MetadataOperationType;
120+
Create?: MetadataOperationType;
121+
Update?: MetadataOperationType;
122+
Patch?: MetadataOperationType;
123+
Delete?: MetadataOperationType;
124+
}
125+
114126
export interface UploadedFile {
115127
fileName?: string
116128
filePath?: string
@@ -378,8 +390,8 @@ export interface AuthInfo {
378390
export interface AutoQueryConvention {
379391
name: string;
380392
value: string;
381-
types: string;
382-
valueType: string;
393+
types?: string;
394+
valueType?: string;
383395
}
384396
export interface AutoQueryInfo {
385397
maxLimit?: number;

src/use/metadata.ts

+40-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type AppMetadata, type MetadataType, type MetadataPropertyType, type MetadataOperationType, type InputInfo, type KeyValuePair, type MetadataTypes, type AutoQueryConvention, type Filter, type RefInfo, type InputProp, type AppInfo, type MetadataTypeName, MetadataApp } from "@/types"
1+
import { type AppMetadata, type MetadataType, type MetadataPropertyType, type MetadataOperationType, type InputInfo, type KeyValuePair, type MetadataTypes, type AutoQueryConvention, type Filter, type RefInfo, type InputProp, type AppInfo, type MetadataTypeName, type AutoQueryApis, MetadataApp } from "@/types"
22
import { toDate, toCamelCase, chop, map, mapGet, toDateTime, leftPart, JsonServiceClient } from '@servicestack/client'
33
import { computed, inject } from 'vue'
44
import { Sole } from './config'
@@ -81,7 +81,7 @@ function typeName(metaType?:MetadataTypeName) {
8181

8282

8383
/** Capture AutoQuery APIs */
84-
export class Apis
84+
export class Apis implements AutoQueryApis
8585
{
8686
Query?: MetadataOperationType;
8787
QueryInto?: MetadataOperationType;
@@ -128,6 +128,17 @@ export class Apis
128128

129129
static forType(type?:string|null, metaTypes?:MetadataTypes|null) {
130130
let apis = new Apis()
131+
if (Sole.config.apisResolver && type) {
132+
const aqApis = Sole.config.apisResolver(type,metaTypes)
133+
if (aqApis) {
134+
apis.Query = aqApis.Query
135+
apis.QueryInto = aqApis.QueryInto
136+
apis.Create = aqApis.Create
137+
apis.Update = aqApis.Update
138+
apis.Patch = aqApis.Patch
139+
apis.Delete = aqApis.Delete
140+
}
141+
}
131142
if (type) {
132143
metaTypes ??= Sole.metadata.value?.api
133144
metaTypes?.operations.forEach(op => {
@@ -406,6 +417,10 @@ async function loadMetadata(args:{
406417
* @param [namespace] - Find MetadataType by name and namespace
407418
*/
408419
export function typeOf(name?:string|null, namespace?:string|null) {
420+
if (Sole.config.typeResolver) {
421+
let type = Sole.config.typeResolver(name!,namespace)
422+
if (type) return type
423+
}
409424
let api = Sole.metadata.value?.api
410425
if (!api || !name) return null
411426
let type = api.types.find(x => x.name.toLowerCase() === name.toLowerCase() && (!namespace || x.namespace == namespace))
@@ -419,6 +434,10 @@ export function typeOf(name?:string|null, namespace?:string|null) {
419434

420435
/** Resolve Request DTO {MetadataOperationType} by name */
421436
export function apiOf(name:string) {
437+
if (Sole.config.apiResolver) {
438+
const op = Sole.config.apiResolver(name)
439+
if (op) return op
440+
}
422441
let api = Sole.metadata.value?.api
423442
if (!api) return null
424443
let requestOp = api.operations.find(x => x.request.name.toLowerCase() === name.toLowerCase())
@@ -669,12 +688,30 @@ export function formatFilterValue(type:string, value:string) {
669688
: `'${value}'`
670689
}
671690

691+
function nv(name:string,value:string) { return { name, value } }
692+
693+
const defaultViewerConventions:AutoQueryConvention[] = [
694+
nv("=","%"),
695+
nv("!=","%!"),
696+
nv(">=",">%"),
697+
nv(">","%>"),
698+
nv("<=","%<"),
699+
nv("<","<%"),
700+
nv("In","%In"),
701+
nv("Between","%Between"),
702+
{ name: "Starts With", value: "%StartsWith", types: "string" },
703+
{ name: "Contains", value: "%Contains", types: "string" },
704+
{ name: "Ends With", value: "%EndsWith", types: "string" },
705+
{ name: "Exists", value: "%IsNotNull", valueType: "none" },
706+
{ name: "Not Exists", value: "%IsNull", valueType: "none" },
707+
]
708+
672709
export function useMetadata() {
673710

674711
/** Reactive accessor to Ref<MetadataTypes> */
675712
const metadataApp = computed<AppInfo|null>(() => Sole.metadata.value?.app || null)
676713
const metadataApi = computed<MetadataTypes|null>(() => Sole.metadata.value?.api || null)
677-
const filterDefinitions = computed<AutoQueryConvention[]>(() => Sole.metadata.value?.plugins.autoQuery.viewerConventions || [])
714+
const filterDefinitions = computed<AutoQueryConvention[]>(() => Sole.metadata.value?.plugins?.autoQuery?.viewerConventions || defaultViewerConventions)
678715

679716
tryLoad()
680717

0 commit comments

Comments
 (0)