Collections module (#158)

* Update folder structure of module

* Add barebones form structure

* Add basic tabular layout implementation

* Add test placeholders for collections module
This commit is contained in:
Rijk van Zanten
2020-03-11 13:36:54 -04:00
committed by GitHub
parent ceead2f93d
commit 97b7bb01b6
14 changed files with 289 additions and 34 deletions

View File

@@ -0,0 +1,4 @@
import CollectionsNavigation from './navigation.vue';
export { CollectionsNavigation };
export default CollectionsNavigation;

View File

@@ -1,10 +1,10 @@
import CollectionsNavigation from './collections-navigation.vue';
import CollectionsNavigation from './navigation.vue';
import VueCompositionAPI from '@vue/composition-api';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import useNavigation from '../compositions/use-navigation';
import useNavigation from '../../compositions/use-navigation';
import VList, { VListItem, VListItemContent } from '@/components/v-list';
jest.mock('../compositions/use-navigation');
jest.mock('../../compositions/use-navigation');
const localVue = createLocalVue();
localVue.use(VueCompositionAPI);

View File

@@ -10,7 +10,7 @@
<script lang="ts">
import { defineComponent } from '@vue/composition-api';
import useNavigation from '../compositions/use-navigation';
import useNavigation from '../../compositions/use-navigation';
export default defineComponent({
props: {},

View File

@@ -1,5 +1,7 @@
import CollectionsOverview from './routes/collections-overview.vue';
import { defineModule } from '@/modules/define';
import CollectionsOverview from './routes/overview/';
import CollectionsBrowse from './routes/browse/';
import CollectionsDetail from './routes/detail/';
export default defineModule({
id: 'collections',
@@ -9,6 +11,16 @@ export default defineModule({
{
path: '/',
component: CollectionsOverview
},
{
path: '/:collection',
component: CollectionsBrowse,
props: true
},
{
path: '/:collection/:primaryKey',
component: CollectionsDetail,
props: true
}
],
icon: 'box'

View File

@@ -0,0 +1,21 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import VueCompositionAPI from '@vue/composition-api';
import CollectionsBrowse from './browse.vue';
import PrivateView from '@/views/private-view';
const localVue = createLocalVue();
localVue.use(VueCompositionAPI);
localVue.component('private-view', PrivateView);
describe('Modules / Collections / Browse', () => {
it('Renders', () => {
const component = shallowMount(CollectionsBrowse, {
localVue,
propsData: {
collection: 'my-test',
primaryKey: 'id'
}
});
expect(component.isVueInstance()).toBe(true);
});
});

View File

@@ -0,0 +1,51 @@
<template>
<private-view v-if="currentCollection" :title="currentCollection.name">
<template #actions>
<v-button rounded icon style="--v-button-background-color: var(--success);">
<v-icon name="add" />
</v-button>
<v-button rounded icon style="--v-button-background-color: var(--warning);">
<v-icon name="delete" />
</v-button>
<v-button rounded icon style="--v-button-background-color: var(--danger);">
<v-icon name="favorite" />
</v-button>
</template>
<template #navigation>
<collections-navigation />
</template>
<layout-tabular :collection="collection" />
</private-view>
<!-- @TODO: Render real 404 view here -->
<p v-else>Not found</p>
</template>
<script lang="ts">
import { defineComponent, computed } from '@vue/composition-api';
import useCollectionsStore from '@/stores/collections';
import { Collection } from '@/stores/collections/types';
import CollectionsNavigation from '../../components/navigation/';
export default defineComponent({
components: { CollectionsNavigation },
props: {
collection: {
type: String,
required: true
}
},
setup(props) {
const collectionsStore = useCollectionsStore();
const currentCollection = computed<Collection | null>(() => {
return (
collectionsStore.state.collections.find(
collection => collection.collection === props.collection
) || null
);
});
return { currentCollection };
}
});
</script>

View File

@@ -0,0 +1,4 @@
import CollectionsBrowse from './browse.vue';
export { CollectionsBrowse };
export default CollectionsBrowse;

View File

@@ -0,0 +1,21 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import VueCompositionAPI from '@vue/composition-api';
import CollectionsDetail from './detail.vue';
import PrivateView from '@/views/private-view';
const localVue = createLocalVue();
localVue.use(VueCompositionAPI);
localVue.component('private-view', PrivateView);
describe('Modules / Collections / Detail', () => {
it('Renders', () => {
const component = shallowMount(CollectionsDetail, {
localVue,
propsData: {
collection: 'my-test',
primaryKey: 'id'
}
});
expect(component.isVueInstance()).toBe(true);
});
});

View File

@@ -0,0 +1,72 @@
<template>
<private-view title="Edit">
<template v-if="item">
<div style="margin-bottom: 20px" v-for="field in visibleFields" :key="field.field">
<p>{{ field.name }}</p>
<interface-text-input
v-if="field.type === 'string'"
:value="item[field.field]"
:options="{}"
/>
<span v-else style="font-family: monospace;">{{ item[field.field] }}</span>
</div>
</template>
<template #navigation>
<collections-navigation />
</template>
</private-view>
</template>
<script lang="ts">
import { defineComponent, computed, ref } from '@vue/composition-api';
import useProjectsStore from '@/stores/projects';
import useFieldsStore from '@/stores/fields';
import { Field } from '@/stores/fields/types';
import api from '@/api';
import CollectionsNavigation from '../../components/navigation/';
export default defineComponent({
components: { CollectionsNavigation },
props: {
collection: {
type: String,
required: true
},
primaryKey: {
type: String,
required: true
}
},
setup(props) {
const { currentProjectKey } = useProjectsStore().state;
const fieldsStore = useFieldsStore();
const fieldsInCurrentCollection = computed<Field[]>(() => {
return fieldsStore.state.fields.filter(field => field.collection === props.collection);
});
const visibleFields = computed<Field[]>(() => {
return fieldsInCurrentCollection.value
.filter(field => field.hidden_browse === false)
.sort((a, b) => (a.sort || Infinity) - (b.sort || Infinity));
});
const item = ref(null);
const loading = ref(false);
const error = ref(null);
fetchItem();
return { visibleFields, item, loading, error };
async function fetchItem() {
loading.value = true;
try {
const response = await api.get(
`/${currentProjectKey}/items/${props.collection}/${props.primaryKey}`
);
item.value = response.data.data;
} catch (error) {
error.value = error;
} finally {
loading.value = false;
}
}
}
});
</script>

View File

@@ -0,0 +1,4 @@
import CollectionsDetail from './detail.vue';
export { CollectionsDetail };
export default CollectionsDetail;

View File

@@ -0,0 +1,4 @@
import CollectionsOverview from './overview.vue';
export { CollectionsOverview };
export default CollectionsOverview;

View File

@@ -1,12 +1,12 @@
import CollectionsOverview from './collections-overview.vue';
import CollectionsOverview from './overview.vue';
import VueCompositionAPI from '@vue/composition-api';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import useNavigation from '../compositions/use-navigation';
import useNavigation from '../../compositions/use-navigation';
import VTable from '@/components/v-table';
import PrivateView from '@/views/private-view/';
import router from '@/router';
jest.mock('../compositions/use-navigation');
jest.mock('../../compositions/use-navigation');
jest.mock('@/router');
const localVue = createLocalVue();

View File

@@ -4,18 +4,6 @@
<v-button rounded disabled icon secondary><v-icon name="box" /></v-button>
</template>
<template #actions>
<v-button rounded icon style="--v-button-background-color: var(--success);">
<v-icon name="add" />
</v-button>
<v-button rounded icon style="--v-button-background-color: var(--warning);">
<v-icon name="delete" />
</v-button>
<v-button rounded icon style="--v-button-background-color: var(--danger);">
<v-icon name="favorite" />
</v-button>
</template>
<template #navigation>
<collections-navigation />
</template>
@@ -30,9 +18,9 @@
<script lang="ts">
import { defineComponent } from '@vue/composition-api';
import CollectionsNavigation from '../components/collections-navigation.vue';
import CollectionsNavigation from '../../components/navigation/';
import { i18n } from '@/lang';
import useNavigation, { NavItem } from '../compositions/use-navigation';
import useNavigation, { NavItem } from '../../compositions/use-navigation';
import router from '@/router';
export default defineComponent({
@@ -58,11 +46,8 @@ export default defineComponent({
value: 'note'
}
];
const { navItems } = useNavigation();
return { tableHeaders, navItems, navigateToCollection };
function navigateToCollection(navItem: NavItem) {
router.push(navItem.to);
}