Skip to content

Commit

Permalink
App type improvements (directus#6151)
Browse files Browse the repository at this point in the history
* Fix v-table interalItems type

* Fix useGroupable return type

* Fix useCollection return type

* Fix useCustomSelection return type

* Fix useElementSize return type

* Fix useFormFields return type

* Fix useItem return type

* Fix useItems return type

* Prepend composable return type name with "Usable"

* Fix usePreset return type

* Fix useScrollDistance return type

* Fix useTitle return type

* Fix useWindowSize return type

* Fix usePermissions return type

* Fix useTemplateData return type

* Fix a few type issues in field store

* Fix extension getter return types

* Fix hydrate store type issue and double-hydrating users store

* Fix code interface type issue

* Fix m2m composables return types

* Fix html editor composables return types

* Fix collections module composables return types

* Fix files module composable return type

* Fix settings module composable return type

* Fix settings module roles composables return types

* Fix settings module users composable return type

* Fix return type issues in utils and a nasty parameter overwrite

* Fix modelValue casing in template
  • Loading branch information
nickrum authored Jun 9, 2021
1 parent 70c8e08 commit 12a3b22
Show file tree
Hide file tree
Showing 43 changed files with 360 additions and 96 deletions.
2 changes: 1 addition & 1 deletion app/src/components/v-table/v-table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ export default defineComponent({
if (internalSort.value.desc === true) return itemsSorted.reverse();
return itemsSorted;
},
set: (value: Record<string, any>) => {
set: (value: Item[]) => {
emit('update:items', value);
},
});
Expand Down
19 changes: 17 additions & 2 deletions app/src/composables/groupable/groupable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ type GroupableOptions = {
watch?: boolean;
};

export function useGroupable(options?: GroupableOptions): Record<string, any> {
type UsableGroupable = {
active: Ref<boolean>;
toggle: () => void;
activate: () => void;
deactivate: () => void;
};

export function useGroupable(options?: GroupableOptions): UsableGroupable {
// Injects the registration / toggle functions from the parent scope
const parentFunctions = inject(options?.group || 'item-group', null);

Expand Down Expand Up @@ -95,6 +102,14 @@ type GroupableParentOptions = {
multiple?: Ref<boolean>;
};

type UsableGroupableParent = {
items: Ref<GroupableInstance[]>;
selection: Ref<readonly (string | number)[]>;
internalSelection: Ref<(string | number)[]>;
getValueForItem: (item: GroupableInstance) => string | number;
updateChildren: () => void;
};

/**
* Used to make a component a group parent component. Provides the registration / toggle functions
* to its group children
Expand All @@ -103,7 +118,7 @@ export function useGroupableParent(
state: GroupableParentState = {},
options: GroupableParentOptions = {},
group = 'item-group'
): Record<string, any> {
): UsableGroupableParent {
// References to the active state and value of the individual child items
const items = shallowRef<GroupableInstance[]>([]);

Expand Down
20 changes: 10 additions & 10 deletions app/src/composables/use-collection/use-collection.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { useCollectionsStore, useFieldsStore } from '@/stores/';
import { Collection, Field } from '@/types';
import { computed, Ref, ref } from 'vue';
import { computed, ref, Ref, ComputedRef } from 'vue';

type CollectionInfo = {
info: Ref<Collection | null>;
fields: Ref<Field[]>;
type UsableCollection = {
info: ComputedRef<Collection | null>;
fields: ComputedRef<Field[]>;
defaults: Record<string, any>;
primaryKeyField: Ref<Field | null>;
userCreatedField: Ref<Field | null>;
sortField: Ref<string | null>;
isSingleton: Ref<boolean>;
accountabilityScope: Ref<'all' | 'activity' | null>;
primaryKeyField: ComputedRef<Field | null>;
userCreatedField: ComputedRef<Field | null>;
sortField: ComputedRef<string | null>;
isSingleton: ComputedRef<boolean>;
accountabilityScope: ComputedRef<'all' | 'activity' | null>;
};

export function useCollection(collectionKey: string | Ref<string | null>): CollectionInfo {
export function useCollection(collectionKey: string | Ref<string | null>): UsableCollection {
const collectionsStore = useCollectionsStore();
const fieldsStore = useFieldsStore();

Expand Down
25 changes: 18 additions & 7 deletions app/src/composables/use-custom-selection/use-custom-selection.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { nanoid } from 'nanoid';
import { computed, ComputedRef, Ref, ref, watch } from 'vue';

type UsableCustomSelection = {
otherValue: Ref<string | null>;
usesOtherValue: ComputedRef<boolean>;
};

export function useCustomSelection(
currentValue: Ref<string>,
items: Ref<any[]>,
emit: (event: string | null) => void
): Record<string, ComputedRef> {
): UsableCustomSelection {
const localOtherValue = ref('');

const otherValue = computed({
Expand Down Expand Up @@ -36,16 +41,22 @@ export function useCustomSelection(
return { otherValue, usesOtherValue };
}

type OtherValue = {
key: string;
value: string;
};

type UsableCustomSelectionMultiple = {
otherValues: Ref<OtherValue[]>;
addOtherValue: (value?: string) => void;
setOtherValue: (key: string, newValue: string | null) => void;
};

export function useCustomSelectionMultiple(
currentValues: Ref<string[]>,
items: Ref<any[]>,
emit: (event: string[] | null) => void
): Record<string, any> {
type OtherValue = {
key: string;
value: string;
};

): UsableCustomSelectionMultiple {
const otherValues = ref<OtherValue[]>([]);

watch(currentValues, (newValue) => {
Expand Down
5 changes: 4 additions & 1 deletion app/src/composables/use-element-size/use-element-size.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ declare global {

export default function useElementSize<T extends Element>(
target: T | Ref<T> | Ref<undefined>
): Record<string, Ref<number>> {
): {
width: Ref<number>;
height: Ref<number>;
} {
const width = ref(0);
const height = ref(0);

Expand Down
4 changes: 2 additions & 2 deletions app/src/composables/use-field-tree/use-field-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useFieldsStore, useRelationsStore } from '@/stores/';
import { Field, Relation } from '@/types';
import { getRelationType } from '@/utils/get-relation-type';
import { cloneDeep } from 'lodash';
import { computed, Ref } from 'vue';
import { computed, Ref, ComputedRef } from 'vue';

type FieldOption = { name: string; field: string; key: string; children?: FieldOption[] };

Expand All @@ -12,7 +12,7 @@ export default function useFieldTree(
strict = false,
inject?: Ref<{ fields: Field[]; relations: Relation[] } | null>,
filter: (field: Field) => boolean = () => true
): { tree: Ref<FieldOption[]> } {
): { tree: ComputedRef<FieldOption[]> } {
const fieldsStore = useFieldsStore();
const relationsStore = useRelationsStore();

Expand Down
2 changes: 1 addition & 1 deletion app/src/composables/use-form-fields/use-form-fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getDefaultInterfaceForType } from '@/utils/get-default-interface-for-ty
import { clone } from 'lodash';
import { computed, ComputedRef, Ref } from 'vue';

export default function useFormFields(fields: Ref<Field[]>): { formFields: ComputedRef } {
export default function useFormFields(fields: Ref<Field[]>): { formFields: ComputedRef<Field[]> } {
const { interfaces } = getInterfaces();

const formFields = computed(() => {
Expand Down
30 changes: 25 additions & 5 deletions app/src/composables/use-item/use-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,34 @@ import { APIError } from '@/types';
import { notify } from '@/utils/notify';
import { unexpectedError } from '@/utils/unexpected-error';
import { AxiosResponse } from 'axios';
import { computed, Ref, ref, watch } from 'vue';

export function useItem(collection: Ref<string>, primaryKey: Ref<string | number | null>): Record<string, any> {
import { computed, ComputedRef, Ref, ref, watch } from 'vue';

type UsableItem = {
edits: Ref<Record<string, any>>;
item: Ref<Record<string, any> | null>;
error: Ref<any>;
loading: Ref<boolean>;
saving: Ref<boolean>;
refresh: () => void;
save: () => Promise<any>;
isNew: ComputedRef<boolean>;
remove: () => Promise<void>;
deleting: Ref<boolean>;
archive: () => Promise<void>;
isArchived: ComputedRef<boolean | null>;
archiving: Ref<boolean>;
saveAsCopy: () => Promise<any>;
isBatch: ComputedRef<boolean>;
getItem: () => Promise<void>;
validationErrors: Ref<any[]>;
};

export function useItem(collection: Ref<string>, primaryKey: Ref<string | number | null>): UsableItem {
const { info: collectionInfo, primaryKeyField } = useCollection(collection);

const item = ref<Record<string, any> | null>(null);
const error = ref(null);
const validationErrors = ref([]);
const error = ref<any>(null);
const validationErrors = ref<any[]>([]);
const loading = ref(false);
const saving = ref(false);
const deleting = ref(false);
Expand Down
8 changes: 4 additions & 4 deletions app/src/composables/use-items/use-items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Filter, Item } from '@/types/';
import filtersToQuery from '@/utils/filters-to-query';
import moveInArray from '@/utils/move-in-array';
import { isEqual, orderBy, throttle } from 'lodash';
import { computed, nextTick, ref, Ref, watch } from 'vue';
import { computed, ComputedRef, nextTick, ref, Ref, watch } from 'vue';

type Query = {
limit: Ref<number>;
Expand All @@ -20,18 +20,18 @@ type ManualSortData = {
to: string | number;
};

type ItemsInfo = {
type UsableItems = {
itemCount: Ref<number | null>;
totalCount: Ref<number | null>;
items: Ref<Item[]>;
totalPages: Ref<number>;
totalPages: ComputedRef<number>;
loading: Ref<boolean>;
error: Ref<any>;
changeManualSort: (data: ManualSortData) => Promise<void>;
getItems: () => Promise<void>;
};

export function useItems(collection: Ref<string | null>, query: Query, fetchOnInit = true): ItemsInfo {
export function useItems(collection: Ref<string | null>, query: Query, fetchOnInit = true): UsableItems {
const { primaryKeyField, sortField } = useCollection(collection);

let loadingTimeout: number | null = null;
Expand Down
15 changes: 10 additions & 5 deletions app/src/composables/use-permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ import { cloneDeep } from 'lodash';
import { isAllowed } from '../utils/is-allowed';
import { useCollection } from './use-collection';

export function usePermissions(
collection: Ref<string>,
item: Ref<any>,
isNew: Ref<boolean>
): Record<string, ComputedRef> {
type UsablePermissions = {
deleteAllowed: ComputedRef<boolean>;
saveAllowed: ComputedRef<boolean>;
archiveAllowed: ComputedRef<boolean>;
updateAllowed: ComputedRef<boolean>;
fields: ComputedRef<Field[]>;
revisionsAllowed: ComputedRef<boolean>;
};

export function usePermissions(collection: Ref<string>, item: Ref<any>, isNew: Ref<boolean>): UsablePermissions {
const userStore = useUserStore();
const permissionsStore = usePermissionsStore();

Expand Down
23 changes: 21 additions & 2 deletions app/src/composables/use-preset/use-preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,32 @@ import { useCollection } from '@/composables/use-collection';
import { usePresetsStore, useUserStore } from '@/stores';
import { Filter, Preset } from '@/types/';
import { debounce, isEqual } from 'lodash';
import { computed, ref, Ref, watch } from 'vue';
import { computed, ComputedRef, ref, Ref, watch } from 'vue';

type UsablePreset = {
bookmarkExists: ComputedRef<boolean>;
layout: Ref<string | null>;
layoutOptions: Ref<Record<string, any>>;
layoutQuery: Ref<Record<string, any>>;
filters: Ref<readonly Filter[]>;
searchQuery: Ref<string | null>;
refreshInterval: Ref<number | null>;
savePreset: (preset?: Partial<Preset> | undefined) => Promise<any>;
saveCurrentAsBookmark: (overrides: Partial<Preset>) => Promise<any>;
bookmarkTitle: Ref<string | null>;
resetPreset: () => Promise<void>;
bookmarkSaved: Ref<boolean>;
bookmarkIsMine: ComputedRef<boolean>;
busy: Ref<boolean>;
clearLocalSave: () => void;
localPreset: Ref<Partial<Preset>>;
};

export function usePreset(
collection: Ref<string>,
bookmark: Ref<number | null> = ref(null),
temporary = false
): Record<string, any> {
): UsablePreset {
const presetsStore = usePresetsStore();
const userStore = useUserStore();

Expand Down
10 changes: 8 additions & 2 deletions app/src/composables/use-scroll-distance/use-scroll-distance.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { throttle } from 'lodash';
import { ComponentPublicInstance, computed, isRef, onMounted, onUnmounted, ref, Ref } from 'vue';
import { ComponentPublicInstance, computed, isRef, onMounted, onUnmounted, ref, Ref, ComputedRef } from 'vue';

type UsableScrollDistance = {
top: Ref<number | undefined>;
left: Ref<number | undefined>;
target: ComputedRef<Element | null>;
};

export default function useScrollDistance<T extends Element>(
t: T | Ref<T | null | ComponentPublicInstance>
): Record<string, Ref> {
): UsableScrollDistance {
const top = ref<number>();
const left = ref<number>();

Expand Down
14 changes: 10 additions & 4 deletions app/src/composables/use-template-data.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import api from '@/api';
import { Collection } from '@/types';
import { getFieldsFromTemplate } from '@/utils/get-fields-from-template';
import { computed, ComputedRef, Ref, ref, watch } from 'vue';
import { computed, Ref, ref, watch } from 'vue';

type UsableTemplateData = {
templateData: Ref<Record<string, any> | undefined>;
loading: Ref<boolean>;
error: Ref<any>;
};

export default function useTemplateData(
collection: ComputedRef<Collection | undefined>,
collection: Ref<Collection | null>,
primaryKey: Ref<string>
): Record<string, any> {
): UsableTemplateData {
const templateData = ref<Record<string, any>>();
const loading = ref(false);
const error = ref(null);
const error = ref<any>(null);

const fields = computed(() => {
if (!collection.value?.meta?.display_template) return null;
Expand Down
2 changes: 1 addition & 1 deletion app/src/composables/use-title/use-title.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ref, Ref, watch } from 'vue';

export function useTitle(newTitle: string | Ref<string>): Ref | undefined {
export function useTitle(newTitle: string | Ref<string>): Ref<string> | undefined {
if (newTitle === undefined || newTitle === null) return;

const titleRef = typeof newTitle === 'string' ? ref(newTitle) : newTitle;
Expand Down
5 changes: 4 additions & 1 deletion app/src/composables/use-window-size/use-window-size.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ type WindowSizeOptions = {
throttle: number;
};

export default function useWindowSize(options: WindowSizeOptions = { throttle: 100 }): Record<string, Ref> {
export default function useWindowSize(options: WindowSizeOptions = { throttle: 100 }): {
width: Ref<number>;
height: Ref<number>;
} {
const width = ref(0);
const height = ref(0);

Expand Down
2 changes: 1 addition & 1 deletion app/src/displays/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import { DisplayConfig } from './types';
const displaysRaw: Ref<DisplayConfig[]> = shallowRef([]);
const displays: Ref<DisplayConfig[]> = shallowRef([]);

export function getDisplays(): Record<string, Ref<DisplayConfig[]>> {
export function getDisplays(): { displays: Ref<DisplayConfig[]>; displaysRaw: Ref<DisplayConfig[]> } {
return { displays, displaysRaw };
}
4 changes: 2 additions & 2 deletions app/src/hydrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '@/stores';

type GenericStore = {
id: string;
$id: string;
hydrate?: () => Promise<void>;
dehydrate?: () => Promise<void>;

Expand Down Expand Up @@ -60,7 +60,7 @@ export async function hydrate(stores = useStores()): Promise<void> {
await userStore.hydrate();

if (userStore.currentUser?.role) {
await Promise.all(stores.filter(({ id }) => id !== 'userStore').map((store) => store.hydrate?.()));
await Promise.all(stores.filter(({ $id }) => $id !== 'userStore').map((store) => store.hydrate?.()));
await registerModules();
await setLanguage((userStore.currentUser?.language as Language) || 'en-US');
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import { InterfaceConfig } from './types';
const interfacesRaw: Ref<InterfaceConfig[]> = shallowRef([]);
const interfaces: Ref<InterfaceConfig[]> = shallowRef([]);

export function getInterfaces(): Record<string, Ref<InterfaceConfig[]>> {
export function getInterfaces(): { interfaces: Ref<InterfaceConfig[]>; interfacesRaw: Ref<InterfaceConfig[]> } {
return { interfaces, interfacesRaw };
}
2 changes: 1 addition & 1 deletion app/src/interfaces/input-code/input-code.vue
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export default defineComponent({
codemirror.setOption('mode', { name: 'javascript', json: true });
CodeMirror.registerHelper('lint', 'json', (text: string) => {
const found: Record<string, any> = [];
const found: Record<string, any>[] = [];
const parser = jsonlint.parser;
parser.parseError = (str: string, hash: any) => {
Expand Down
Loading

0 comments on commit 12a3b22

Please sign in to comment.