Skip to content

Commit

Permalink
fix: adjust some types around metadata components to better reflect a…
Browse files Browse the repository at this point in the history
…ctual function
  • Loading branch information
ascott18 committed Aug 17, 2023
1 parent 0f999ce commit 08ded59
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
md="4"
lg="3"
>
<!-- <c-input
<c-input
v-model="caller.args[param.name]"
:for="param"
hide-details="auto"
/> -->
<c-input :model="caller" :for="param.name" hide-details="auto" />
/>
<!-- <c-input :model="caller" :for="param.name" hide-details="auto" /> -->
</v-col>
</v-row>
</v-col>
Expand Down
49 changes: 28 additions & 21 deletions src/coalesce-vue-vuetify2/src/components/c-metadata-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,9 @@ import {

export type ForSpec = undefined | null | string | Property | Value | Method;

export function getModelAndValueMeta(
export function getValueMetaAndOwner(
forVal: ForSpec,
model:
| Model<ClassType>
| DataSource<DataSourceType>
| AnyArgCaller
| null
| undefined,
model: Model | DataSource | AnyArgCaller | null | undefined,
$metadata?: Domain
) {
const valueMeta = getValueMeta(forVal, model?.$metadata, $metadata);
Expand All @@ -49,7 +44,7 @@ export function getModelAndValueMeta(
model = model.args;
}

return { valueMeta, model };
return { valueMeta, valueOwner: model as any };
}

export function getValueMeta(
Expand Down Expand Up @@ -218,7 +213,7 @@ export function getValueMeta(
};
}
}

return tail as Property | Value;
}

Expand All @@ -233,8 +228,6 @@ export function buildVuetifyAttrs(
};
}

const modelMeta = model ? model.$metadata : null;

return {
// If a label is not provided to the component, default to the displayName of the value.
label: valueMeta?.displayName,
Expand All @@ -250,7 +243,7 @@ export function buildVuetifyAttrs(
// We're bound to a ViewModel instance, and the value is a prop on that viewmodel. Ask the ViewModel for the rules.
model &&
model instanceof ViewModel &&
valueMeta.name in (modelMeta as ModelType)!.props
valueMeta.name in model.$metadata!.props
? model.$getRules(valueMeta.name)
: // Grab the rules from the metadata for the bound value
"rules" in valueMeta && valueMeta.rules
Expand All @@ -261,10 +254,15 @@ export function buildVuetifyAttrs(
};
}

export function makeMetadataProps<TModel = Model<ClassType>>() {
type ModelAllowedType = Model | AnyArgCaller;

export function makeMetadataProps<TModel extends ModelAllowedType = Model>() {
return {
/** An object owning the value that is specified by the `for` prop. */
model: { type: [Object, Function] as PropType<TModel | null>, default: null },
model: {
type: [Object, Function] as PropType<TModel | null>,
default: null,
},

/** A metadata specifier for the value being bound. One of:
* * A string with the name of the value belonging to `model`. E.g. `"firstName"`.
Expand All @@ -279,11 +277,16 @@ export function makeMetadataProps<TModel = Model<ClassType>>() {
};
}

export function useMetadataProps(
props: ExtractPropTypes<ReturnType<typeof makeMetadataProps<Model<ClassType>>>>
) {
export function useMetadataProps<
TModel extends ModelAllowedType = Model
>(props: {
model: TModel | null | undefined;
for: ForSpec | null | undefined;
}) {
const modelMeta = computed(() => {
return props.model ? props.model.$metadata : null;
return props.model
? (props.model.$metadata as any as TModel["$metadata"])
: null;
});

const instance = getCurrentInstance();
Expand All @@ -300,9 +303,13 @@ export function useMetadataProps(
}) as () => Property | Value | null);

/** The object that owns the value described by `valueMeta`. */
const valueOwner = computed((() => {
return getModelAndValueMeta(props.for, props.model, instance!.proxy.$coalesce.metadata).model;
}) as () => any);
const valueOwner = computed(() => {
return getValueMetaAndOwner(
props.for,
props.model,
instance!.proxy.$coalesce.metadata
).valueOwner;
});

const inputBindAttrs = computed(() =>
buildVuetifyAttrs(valueMeta.value, props.model, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,13 @@ import {
startOfDay,
} from "date-fns";
import { format, utcToZonedTime, zonedTimeToUtc } from "date-fns-tz";
import { DateKind, getDefaultTimeZone, parseDateUserInput } from "coalesce-vue";
import {
AnyArgCaller,
DateKind,
Model,
getDefaultTimeZone,
parseDateUserInput,
} from "coalesce-vue";
import { defineComponent, PropType } from "vue";
import { makeMetadataProps, useMetadataProps } from "../c-metadata-component";
Expand All @@ -189,7 +195,7 @@ export default defineComponent({
},
props: {
...makeMetadataProps(),
...makeMetadataProps<Model | AnyArgCaller>(),
value: { required: false, type: Date as PropType<Date | null | undefined> },
dateKind: { type: String as PropType<DateKind | null | undefined> },
dateFormat: { type: String },
Expand Down
20 changes: 8 additions & 12 deletions src/coalesce-vue-vuetify2/src/components/input/c-input.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { defineComponent, type PropOptions, type VNodeData } from "vue";
import {
buildVuetifyAttrs,
getModelAndValueMeta,
getValueMetaAndOwner,
makeMetadataProps,
} from "../c-metadata-component";
import {
Model,
ClassType,
DataSource,
DataSourceType,
mapValueToModel,
AnyArgCaller,
parseValue,
Expand Down Expand Up @@ -42,17 +40,15 @@ export default defineComponent({
functional: true,

props: {
...makeMetadataProps<
Model<ClassType> | DataSource<DataSourceType> | AnyArgCaller
>(),
...makeMetadataProps<Model | DataSource | AnyArgCaller>(),

value: <PropOptions<any>>{ required: false },
},

render(_c, ctx) {
// NOTE: CreateElement fn must be named `_c` for unplugin-vue-components to work correctly.

const { valueMeta: _valueMeta, model } = getModelAndValueMeta(
const { valueMeta: _valueMeta, valueOwner } = getValueMetaAndOwner(
ctx.props.for,
ctx.props.model,
ctx.parent.$coalesce.metadata
Expand All @@ -72,8 +68,8 @@ export default defineComponent({

props: {
// If a model is provided, pull the value off the model.
value: model
? (model as any)[valueMeta.name]
value: valueOwner
? valueOwner[valueMeta.name]
: primitiveTypes.includes(valueMeta.type)
? mapValueToModel(ctx.props.value, valueMeta)
: ctx.props.value,
Expand Down Expand Up @@ -126,13 +122,13 @@ export default defineComponent({
// that delegate directly to vuetify components.
const attrs = (data.attrs = buildVuetifyAttrs(
valueMeta,
model,
ctx.props.model,
ctxData.attrs
));

const onInput = function (value: any) {
if (model && valueMeta) {
(model as any)[valueMeta.name] = parseValue(value, valueMeta);
if (valueOwner && valueMeta) {
valueOwner[valueMeta.name] = parseValue(value, valueMeta);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<script lang="ts">
import { defineComponent } from "vue";
import { convertValueToModel } from "coalesce-vue";
import { AnyArgCaller, Model, convertValueToModel } from "coalesce-vue";
import { makeMetadataProps, useMetadataProps } from "../c-metadata-component";
export default defineComponent({
Expand All @@ -31,7 +31,7 @@ export default defineComponent({
},
props: {
...makeMetadataProps(),
...makeMetadataProps<Model | AnyArgCaller>(),
value: { required: false, type: Array },
},
Expand Down
3 changes: 2 additions & 1 deletion src/coalesce-vue-vuetify2/src/components/input/c-select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import {
ItemApiStateWithArgs,
ViewModel,
ModelValue,
AnyArgCaller,
mapParamsToDto,
getMessageForError,
mapValueToModel,
Expand All @@ -110,7 +111,7 @@ export default defineComponent({
},
props: {
...makeMetadataProps(),
...makeMetadataProps<Model | AnyArgCaller>(),
clearable: { required: false, default: undefined, type: Boolean },
readonly: { required: false, default: undefined, type: Boolean },
disabled: { required: false, default: undefined, type: Boolean },
Expand Down
36 changes: 18 additions & 18 deletions src/coalesce-vue-vuetify3/src/components/c-metadata-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,14 @@ import {
ApiState,
DataSource,
} from "coalesce-vue";
import { computed, PropType, useAttrs, ExtractPropTypes } from "vue";
import { computed, PropType, useAttrs } from "vue";
import { useMetadata } from "..";

export type ForSpec = undefined | null | string | Property | Value | Method;

export function getModelAndValueMeta(
export function getValueMetaAndOwner(
forVal: ForSpec,
model:
| Model<ClassType>
| DataSource<DataSourceType>
| AnyArgCaller
| null
| undefined,
model: Model | DataSource | AnyArgCaller | null | undefined,
$metadata?: Domain
) {
const valueMeta = getValueMeta(forVal, model?.$metadata, $metadata);
Expand All @@ -43,7 +38,7 @@ export function getModelAndValueMeta(
model = model.args;
}

return { valueMeta, model };
return { valueMeta, valueOwner: model as any };
}

export function getValueMeta(
Expand Down Expand Up @@ -261,7 +256,9 @@ export function buildVuetifyAttrs(
};
}

export function makeMetadataProps<TModel = Model<ClassType>>() {
type ModelAllowedType = Model | AnyArgCaller;

export function makeMetadataProps<TModel extends ModelAllowedType = Model>() {
return {
/** An object owning the value that is specified by the `for` prop. */
model: {
Expand All @@ -282,16 +279,19 @@ export function makeMetadataProps<TModel = Model<ClassType>>() {
};
}

export function useMetadataProps(
props: ExtractPropTypes<
ReturnType<typeof makeMetadataProps<Model<ClassType>>>
>,
export function useMetadataProps<TModel extends ModelAllowedType = Model>(
props: {
model: TModel | null | undefined;
for: ForSpec | null | undefined;
},
transformValueMeta?: (meta: Value | Property) => Value | Property
) {
const metadata = useMetadata();

const modelMeta = computed(() => {
return props.model ? props.model.$metadata : null;
return props.model
? (props.model.$metadata as any as TModel["$metadata"])
: null;
});

const valueMeta = computed((() => {
Expand All @@ -303,9 +303,9 @@ export function useMetadataProps(
}) as () => Property | Value | null);

/** The object that owns the value described by `valueMeta`. */
const valueOwner = computed((() => {
return getModelAndValueMeta(props.for, props.model, metadata).model;
}) as () => any);
const valueOwner = computed(() => {
return getValueMetaAndOwner(props.for, props.model, metadata).valueOwner;
});

const inputBindAttrs = computed(() =>
buildVuetifyAttrs(valueMeta.value, props.model, useAttrs())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,13 @@ import {
startOfDay,
} from "date-fns";
import { format, utcToZonedTime, zonedTimeToUtc } from "date-fns-tz";
import { getDefaultTimeZone, parseDateUserInput, DateKind } from "coalesce-vue";
import {
getDefaultTimeZone,
parseDateUserInput,
DateKind,
AnyArgCaller,
Model,
} from "coalesce-vue";
import { defineComponent, PropType, ref } from "vue";
import { makeMetadataProps, useMetadataProps } from "../c-metadata-component";
Expand All @@ -105,7 +111,7 @@ export default defineComponent({
},
props: {
...makeMetadataProps(),
...makeMetadataProps<Model | AnyArgCaller>(),
modelValue: {
required: false,
type: Date as PropType<Date | null | undefined>,
Expand Down
Loading

0 comments on commit 08ded59

Please sign in to comment.