Skip to content

Commit

Permalink
Implement front-end routing #4
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobtylerwalls committed Aug 9, 2024
1 parent fb7c2f4 commit c6e16cc
Show file tree
Hide file tree
Showing 12 changed files with 233 additions and 98 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- Added compatibility with PrimeVue 4 [#16](https://github.com/archesproject/arches-references/pull/16)
- Add compatibility with PrimeVue 4 [#9](https://github.com/archesproject/arches-references/issues/9)
- Add front-end routing [#19](https://github.com/archesproject/arches-references/pull/19)

### Changed
- Generate URIs when not supplied [#17](https://github.com/archesproject/arches-references/pull/17)
- Generate URIs when not supplied [#17](https://github.com/archesproject/arches-references/pull/17)

### Fixed

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
import ko from 'knockout';
import ControlledListsMain from '@/arches_references/components/ControlledListsMain.vue';
import { definePreset } from '@primevue/themes';
import Aura from '@primevue/themes/aura';

import ControlledListManager from '@/arches_references/plugins/ControlledListManager.vue';
import createVueApplication from 'utils/create-vue-application';
import ControlledListManagerTemplate from 'templates/views/components/plugins/controlled-list-manager.htm';

import { createRouter, createWebHistory } from 'vue-router';

const routes = [
{ path: '/plugins/controlled-list-manager', name: 'splash', component: ControlledListsMain },
{ path: '/plugins/controlled-list-manager/list/:id', name: 'list', component: ControlledListsMain },
{ path: '/plugins/controlled-list-manager/item/:id', name: 'item', component: ControlledListsMain },
];

const router = createRouter({
history: createWebHistory(),
routes,
});

// Much of this might get merged upstream to core arches in 8.0?
const ControlledListsPreset = definePreset(Aura, {
primitive: {
Expand Down Expand Up @@ -65,6 +79,7 @@ const controlledListsTheme = {
ko.components.register('controlled-list-manager', {
viewModel: function() {
createVueApplication(ControlledListManager, controlledListsTheme).then((vueApp) => {
vueApp.use(router);
vueApp.mount('#controlled-list-manager-mounting-point');
});
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
<script setup lang="ts">
import arches from "arches";
import { computed, provide, ref } from "vue";
import { useRouter } from "vue-router";
import ConfirmDialog from "primevue/confirmdialog";
import ProgressSpinner from "primevue/progressspinner";
import Splitter from "primevue/splitter";
import SplitterPanel from "primevue/splitterpanel";
import Toast from "primevue/toast";
import {
displayedRowKey,
routes,
selectedLanguageKey,
} from "@/arches_references/constants.ts";
import { dataIsList } from "@/arches_references/utils.ts";
Expand All @@ -21,11 +25,23 @@ import type { Ref } from "vue";
import type { Language } from "@/arches/types";
import type { Selectable } from "@/arches_references/types";
const splash = "splash";
const router = useRouter();
const displayedRow: Ref<Selectable | null> = ref(null);
const setDisplayedRow = (val: Selectable | null) => {
displayedRow.value = val;
if (val === null) {
router.push({ name: routes.splash });
return;
}
if (typeof val.id === "number") {
return;
}
if (dataIsList(val)) {
router.push({ name: routes.list, params: { id: val.id } });
} else {
router.push({ name: routes.item, params: { id: val.id } });
}
};
// @ts-expect-error vue-tsc doesn't like arbitrary properties here
provide(displayedRowKey, { displayedRow, setDisplayedRow });
Expand All @@ -49,37 +65,64 @@ const panel = computed(() => {
</script>

<template>
<div class="list-editor-container">
<ListHeader />
<Splitter style="height: 100%">
<SplitterPanel
:size="34"
:min-size="25"
style="display: flex; flex-direction: column"
>
<Suspense>
<ListTree />
<template #fallback>
<ProgressSpinner />
</template>
</Suspense>
</SplitterPanel>
<SplitterPanel
:size="66"
:min-size="25"
:style="{
margin: '1rem 0rem 4rem 1rem',
overflowY: 'auto',
paddingRight: '4rem',
}"
>
<component
:is="panel"
:key="displayedRow?.id ?? splash"
/>
</SplitterPanel>
</Splitter>
<!-- Subtract size of arches toolbars -->
<div style="width: calc(100vw - 50px); height: calc(100vh - 50px)">
<div class="list-editor-container">
<ListHeader />
<Splitter style="height: 100%">
<SplitterPanel
:size="34"
:min-size="25"
style="display: flex; flex-direction: column"
>
<Suspense>
<ListTree />
<template #fallback>
<ProgressSpinner />
</template>
</Suspense>
</SplitterPanel>
<SplitterPanel
:size="66"
:min-size="25"
:style="{
margin: '1rem 0rem 4rem 1rem',
overflowY: 'auto',
paddingRight: '4rem',
}"
>
<component
:is="panel"
:key="displayedRow?.id ?? routes.splash"
/>
</SplitterPanel>
</Splitter>
</div>
</div>
<Toast />
<ConfirmDialog
:draggable="false"
:pt="{
root: {
style: {
fontSize: 'small',
},
},
header: {
style: {
background: 'var(--p-primary-950)',
color: 'white',
borderRadius: '1rem',
marginBottom: '1rem',
},
},
title: {
style: {
fontWeight: 800,
},
},
}"
/>
</template>

<style scoped>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import {
METADATA_CHOICES,
itemKey,
} from "@/arches_references/constants.ts";
import { dataIsNew, languageNameFromCode, shouldUseContrast } from "@/arches_references/utils.ts";
import {
dataIsNew,
languageNameFromCode,
shouldUseContrast,
} from "@/arches_references/utils.ts";
import AddMetadata from "@/arches_references/components/editor/AddMetadata.vue";
import type { Ref } from "vue";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { useGettext } from "vue3-gettext";
import { useConfirm } from "primevue/useconfirm";
import { useToast } from "primevue/usetoast";
import Button from "primevue/button";
import ConfirmDialog from "primevue/confirmdialog";
import SplitButton from "primevue/splitbutton";
import {
Expand Down Expand Up @@ -113,7 +112,6 @@ const createList = () => {
};
nextNewList.value = newList;
newListFormValue.value = "";
newListCounter.value += 1;
tree.value.push(listAsNode(newList, selectedLanguage.value));
Expand Down Expand Up @@ -262,29 +260,6 @@ await fetchListsAndPopulateTree();
:severity="shouldUseContrast() ? CONTRAST : PRIMARY"
@click="createList"
/>
<ConfirmDialog
:draggable="false"
:pt="{
root: {
style: {
fontSize: 'small',
},
},
header: {
style: {
background: 'var(--p-primary-950)',
color: 'white',
borderRadius: '1rem',
marginBottom: '1rem',
},
},
title: {
style: {
fontWeight: 800,
},
},
}"
/>
<SplitButton
class="list-button"
:label="$gettext('Delete')"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ const { setDisplayedRow } = inject(displayedRowKey) as unknown as {
};
const updateSelectedAndExpanded = (node: TreeNode) => {
if (isMultiSelecting.value || movingItem.value?.key) {
return;
}
setDisplayedRow(node.data);
expandedKeys.value = {
...expandedKeys.value,
Expand Down Expand Up @@ -169,7 +173,7 @@ const ptNodeContent = ({ instance }: TreePassThroughMethodOptions) => {
<template>
<ListTreeControls
:key="refetcher"
v-model="tree"
v-model:tree="tree"
v-model:rerender-tree="rerenderTree"
v-model:expanded-keys="expandedKeys"
v-model:selected-keys="selectedKeys"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
<script setup lang="ts">
import { inject, watch } from "vue";
import { useRoute } from "vue-router";
import { displayedRowKey, routes } from "@/arches_references/constants.ts";
import { findNodeInTree } from "@/arches_references/utils.ts";
import ActionBanner from "@/arches_references/components/tree/ActionBanner.vue";
import AddDeleteControls from "@/arches_references/components/tree/AddDeleteControls.vue";
import PresentationControls from "@/arches_references/components/tree/PresentationControls.vue";
import type { RouteLocationNormalizedLoadedGeneric } from "vue-router";
import type { TreeExpandedKeys, TreeSelectionKeys } from "primevue/tree";
import type { TreeNode } from "primevue/treenode";
import type { ControlledList } from "@/arches_references/types";
import type { ControlledList, RowSetter } from "@/arches_references/types";
const controlledListItemsTree = defineModel<TreeNode[]>({ required: true });
const controlledListItemsTree = defineModel<TreeNode[]>("tree", {
required: true,
});
const rerenderTree = defineModel<number>("rerenderTree", { required: true });
const expandedKeys = defineModel<TreeExpandedKeys>("expandedKeys", {
required: true,
Expand All @@ -24,6 +32,75 @@ const newListFormValue = defineModel<string>("newListFormValue", {
required: true,
});
const { setDisplayedRow } = inject(displayedRowKey) as unknown as {
setDisplayedRow: RowSetter;
};
const route = useRoute();
watch(
[
() => {
return { ...route };
},
],
([newRoute]) => {
navigate(newRoute);
},
);
const navigate = (newRoute: RouteLocationNormalizedLoadedGeneric) => {
switch (newRoute.name) {
case routes.splash:
setDisplayedRow(null);
expandedKeys.value = {};
selectedKeys.value = {};
break;
case routes.list: {
if (!controlledListItemsTree.value.length) {
return;
}
const list = controlledListItemsTree.value.find(
(node) => node.data.id === newRoute.params.id,
);
if (list) {
setDisplayedRow(list.data);
expandedKeys.value = {
...expandedKeys.value,
[list.data.id]: true,
};
selectedKeys.value = { [list.data.id]: true };
} else {
setDisplayedRow(null);
}
break;
}
case routes.item: {
if (!controlledListItemsTree.value.length) {
return;
}
const { found, path } = findNodeInTree(
controlledListItemsTree.value,
newRoute.params.id as string,
);
if (found) {
setDisplayedRow(found.data);
const itemsToExpandIds = path.map(
(itemInPath: TreeNode) => itemInPath.key,
);
expandedKeys.value = {
...expandedKeys.value,
...Object.fromEntries(
[
found.data.controlled_list_id,
...itemsToExpandIds,
].map((x) => [x, true]),
),
};
selectedKeys.value = { [found.data.id]: true };
}
break;
}
}
};
const expandAll = () => {
for (const node of controlledListItemsTree.value) {
expandNode(node);
Expand All @@ -43,6 +120,15 @@ const expandNode = (node: TreeNode) => {
}
}
};
// Navigate on initial load of the tree.
watch(
controlledListItemsTree,
() => {
navigate(route);
},
{ once: true },
);
</script>

<template>
Expand Down
Loading

0 comments on commit c6e16cc

Please sign in to comment.