Skip to content

Commit

Permalink
chore: refactor services/project call out of components using composa…
Browse files Browse the repository at this point in the history
…bles (#1785)
  • Loading branch information
echl authored Sep 22, 2023
1 parent e8ae6dc commit d375c5d
Show file tree
Hide file tree
Showing 49 changed files with 430 additions and 502 deletions.
43 changes: 6 additions & 37 deletions packages/client/hmi-client/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,10 @@
<Toast position="top-right" group="warn" />
<Toast position="bottom-right" group="info" />
<Toast position="bottom-right" group="success" />
<tera-navbar
class="header"
:active="!isErrorState"
:current-project-id="project?.id ?? null"
:projects="projects"
:show-suggestions="showSuggestions"
/>
<tera-navbar class="header" :active="!isErrorState" :show-suggestions="showSuggestions" />
<main>
<router-view v-slot="{ Component }">
<component class="page" ref="pageRef" :is="Component" :project="project" />
<component class="page" ref="pageRef" :is="Component" />
</router-view>
</main>
<footer class="footer">
Expand Down Expand Up @@ -80,18 +74,17 @@
</template>

<script setup lang="ts">
import { computed, shallowRef, ref, watch } from 'vue';
import { computed, ref, watch } from 'vue';
import Toast from 'primevue/toast';
import Button from 'primevue/button';
import { ToastSummaries, ToastSeverity, useToastService } from '@/services/toast';
import { useRoute, useRouter } from 'vue-router';
import API from '@/api/api';
import TeraNavbar from '@/components/navbar/tera-navbar.vue';
import * as ProjectService from '@/services/project';
import useResourcesStore from '@/stores/resources';
import { IProject } from '@/types/Project';
import { ResourceType } from '@/types/common';
import TeraModal from '@/components/widgets/tera-modal.vue';
import { useProjects } from '@/composables/project';
import { useCurrentRoute } from './router/index';
const toast = useToastService();
Expand All @@ -115,13 +108,7 @@ const showSuggestions = computed(() => {
/**
* Project
*
* As we use only one Project per application instance.
* It is loaded at the root and passed to all views as prop.
*/
const resourcesStore = useResourcesStore();
const project = shallowRef<IProject | null>(null);
const projects = shallowRef<IProject[] | null>(null);
API.interceptors.response.use(
(response) => response,
Expand All @@ -139,34 +126,16 @@ API.interceptors.response.use(
}
);
async function fetchProject(id: IProject['id']) {
resourcesStore.reset();
// fetch basic metadata about project assets and save them into a global store/cache
resourcesStore.setActiveProject(await ProjectService.get(id, true));
}
watch(
() => route.params.projectId,
async (projectId) => {
// If the projectId or the Project are null, set the Project to null.
if (projectId && !!projectId) {
fetchProject(projectId as IProject['id']);
} else {
resourcesStore.setActiveProject(null);
}
useProjects().get(projectId as IProject['id']);
// Refetch the list of all projects
projects.value = (await ProjectService.getAll()) as unknown as IProject[];
useProjects().getAll();
},
{ immediate: true }
);
// This is crucial - every time the resource store is modified the project prop will be updated to match it
// Once you update assets within a project (add/remove) the project service sets the resource store to what's in the project in the backend
resourcesStore.$subscribe((_mutation, state) => {
project.value = state.activeProject;
});
const isAboutModalVisible = ref(false);
const documentation = computed(() => {
Expand Down
35 changes: 19 additions & 16 deletions packages/client/hmi-client/src/components/code/tera-code.vue
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ import 'ace-builds/src-noconflict/mode-julia';
import 'ace-builds/src-noconflict/mode-r';
import Button from 'primevue/button';
import {
uploadCodeToProject,
getCodeFileAsText,
getCodeAsset,
updateCodeAsset,
uploadCodeToProject,
setFileExtension,
getProgrammingLanguage
} from '@/services/code';
Expand All @@ -137,23 +137,20 @@ import TeraModal from '@/components/widgets/tera-modal.vue';
import InputText from 'primevue/inputtext';
import router from '@/router';
import { RouteName } from '@/router/routes';
import useResourceStore from '@/stores/resources';
import FileUpload from 'primevue/fileupload';
import { IProject } from '@/types/Project';
import Textarea from 'primevue/textarea';
import TeraAsset from '@/components/asset/tera-asset.vue';
import { useProjects } from '@/composables/project';
import Dropdown from 'primevue/dropdown';
const INITIAL_TEXT = '# Paste some code here';
const props = defineProps<{
project: IProject;
assetId: string;
}>();
const emit = defineEmits(['asset-loaded']);
const resourceStore = useResourceStore();
const toast = useToastService();
const codeName = ref('');
Expand Down Expand Up @@ -194,7 +191,9 @@ function onSelectedTextChange() {
async function saveCode() {
// programmingLanguage.value = getProgrammingLanguage(codeName.value);
const existingCode = resourceStore.activeProjectAssets?.code.find((c) => c.id === props.assetId);
const existingCode = useProjects().activeProject.value?.assets?.code.find(
(c) => c.id === props.assetId
);
if (existingCode?.id) {
codeName.value = setFileExtension(codeName.value, programmingLanguage.value);
const file = new File([codeText.value], codeName.value);
Expand All @@ -218,22 +217,26 @@ async function saveCode() {
async function saveNewCode() {
newCodeName.value = setFileExtension(newCodeName.value, programmingLanguage.value);
const file = new File([codeText.value], newCodeName.value);
const newCodeAsset = await uploadCodeToProject(props.project.id, file, progress);
if (!newCodeAsset) {
toast.error('', 'Unable to save file');
} else {
toast.success('', `File saved as ${newCodeName.value}`);
codeAsset.value = newCodeAsset;
const newCode = await uploadCodeToProject(file, progress);
let newAsset;
if (newCode && newCode.id) {
newAsset = await useProjects().addAsset(AssetType.Code, newCode.id);
}
if (newAsset) {
toast.success('', `File saved as ${codeName.value}`);
codeAsset.value = newCode;
router.push({
name: RouteName.Project,
params: {
pageType: AssetType.Code,
projectId: props.project.id,
assetId: codeAsset.value.id
projectId: useProjects().activeProject.value?.id,
assetId: codeAsset?.value?.id
}
});
return newCode;
}
return newCodeAsset;
toast.error('', 'Unable to save file');
return newCode;
}
async function extractModel() {
Expand All @@ -249,7 +252,7 @@ async function extractModel() {
name: RouteName.Project,
params: {
pageType: AssetType.Models,
projectId: props.project.id,
projectId: useProjects().activeProject.value?.id,
assetId: extractedModelId
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
</div>
<tera-jupyter-chat
ref="chat"
:project="props.project"
:show-jupyter-settings="true"
:show-chat-thoughts="props.showChatThoughts"
:jupyter-session="jupyterSession"
Expand Down Expand Up @@ -106,8 +105,6 @@ import Button from 'primevue/button';
import InputText from 'primevue/inputtext';
// import { cloneDeep } from 'lodash';
import { useToastService } from '@/services/toast';
import { addAsset } from '@/services/project';
import { IProject } from '@/types/Project';
import { IModel } from '@jupyterlab/services/lib/session/session';
import { AssetType, CsvAsset, NotebookSession } from '@/types/Types';
import TeraJupyterChat from '@/components/llm/tera-jupyter-chat.vue';
Expand All @@ -125,6 +122,7 @@ import Dropdown from 'primevue/dropdown';
import { shutdownKernel } from '@jupyterlab/services/lib/kernel/restapi';
import ConfirmDialog from 'primevue/confirmdialog';
import { useConfirm } from 'primevue/useconfirm';
import { useProjects } from '@/composables/project';
// import { createNewDataset } from '@/services/dataset';
Expand All @@ -137,7 +135,6 @@ const confirm = useConfirm();
const props = defineProps<{
assetIds: string[];
project?: IProject;
showKernels: boolean;
showChatThoughts: boolean;
notebookSession?: NotebookSession;
Expand Down Expand Up @@ -373,12 +370,12 @@ const updateKernelList = () => {
};
const onNewDatasetSaved = async (payload) => {
if (!props.project) {
if (!useProjects().activeProject.value) {
toast.error('Unable to save dataset', "Can't find active an project");
return;
}
const datasetId = payload.dataset_id;
await addAsset(props.project.id, AssetType.Datasets, datasetId);
await useProjects().addAsset(AssetType.Datasets, datasetId);
emit('new-dataset-saved', { id: datasetId, name: saveAsName.value });
toast.success(
'Dataset saved successfully',
Expand Down
15 changes: 5 additions & 10 deletions packages/client/hmi-client/src/components/dataset/tera-dataset.vue
Original file line number Diff line number Diff line change
Expand Up @@ -284,11 +284,10 @@ import { downloadRawFile, getDataset, updateDataset } from '@/services/dataset';
import { Artifact, CsvAsset, Dataset, DatasetColumn } from '@/types/Types';
import TeraDatasetDatatable from '@/components/dataset/tera-dataset-datatable.vue';
import TeraAsset from '@/components/asset/tera-asset.vue';
import { IProject } from '@/types/Project';
import useResourcesStore from '@/stores/resources';
import * as ProjectService from '@/services/project';
import TeraRelatedPublications from '@/components/widgets/tera-related-publications.vue';
import { AcceptedExtensions, FeatureConfig, ResourceType } from '@/types/common';
import Menu from 'primevue/menu';
import { useProjects } from '@/composables/project';
enum DatasetView {
DESCRIPTION,
Expand All @@ -308,17 +307,13 @@ const props = defineProps({
highlight: {
type: String,
default: null
},
project: {
type: Object as PropType<IProject> | null,
default: null
}
});
const publications = computed(
() =>
props.project?.assets?.artifacts
.filter((artifact: Artifact) =>
useProjects()
.activeProject.value?.assets?.artifacts.filter((artifact: Artifact) =>
[AcceptedExtensions.PDF, AcceptedExtensions.TXT, AcceptedExtensions.MD].some((extension) =>
artifact.fileNames[0].endsWith(extension)
)
Expand Down Expand Up @@ -386,7 +381,7 @@ async function updateDatasetName() {
datasetClone.name = newDatasetName.value;
await updateDataset(datasetClone);
dataset.value = await getDataset(props.assetId);
useResourcesStore().setActiveProject(await ProjectService.get(props.project.id, true));
useProjects().get();
isRenamingDataset.value = false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@
<tera-import-github-file
:urlString="url"
:show-import-button="!featureConfig.isPreview"
:project="project"
@open-code="openCode"
/>
</li>
Expand Down Expand Up @@ -248,7 +247,6 @@ import * as textUtil from '@/utils/text';
import Image from 'primevue/image';
import { generatePdfDownloadLink } from '@/services/generate-download-link';
import TeraAsset from '@/components/asset/tera-asset.vue';
import { IProject } from '@/types/Project';
enum DocumentView {
EXRACTIONS = 'extractions',
Expand All @@ -271,10 +269,6 @@ const props = defineProps({
featureConfig: {
type: Object as PropType<FeatureConfig>,
default: { isPreview: false } as FeatureConfig
},
project: {
type: Object as PropType<IProject> | null,
default: null
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@
</template>

<script setup lang="ts">
import { computed, onMounted, PropType, ref } from 'vue';
import { computed, PropType } from 'vue';
import { AssetType, Document, DocumentAsset } from '@/types/Types';
import useResourcesStore from '@/stores/resources';
import { IProject } from '@/types/Project';
import * as ProjectService from '@/services/project';
import { addDocuments } from '@/services/external';
import dropdown from 'primevue/dropdown';
import { useProjects } from '@/composables/project';
const props = defineProps({
selectedDocument: {
Expand All @@ -38,10 +36,8 @@ const props = defineProps({
});
const emit = defineEmits(['close']);
const resources = useResourcesStore();
const projectsList = ref<IProject[]>([]);
const projectsNames = computed(() => projectsList.value.map((p) => p.name));
const projectsNames = computed(() => useProjects().allProjects?.value?.map((p) => p.name));
const addResourcesToProject = async (projectId: string) => {
// send selected items to the store
Expand All @@ -54,16 +50,12 @@ const addResourcesToProject = async (projectId: string) => {
// first, insert into the proper table/collection
const res = await addDocuments(body);
if (res && resources.activeProject) {
if (res && useProjects().activeProject.value) {
const documentId = res.id;
// then, link and store in the project assets
const assetsType = AssetType.Publications;
await ProjectService.addAsset(projectId, assetsType, documentId);
// update local copy of project assets
// @ts-ignore
resources.activeProject?.assets?.[AssetType.Publications].push(documentId, body);
await useProjects().addAsset(assetsType, documentId, projectId);
}
};
Expand All @@ -73,24 +65,17 @@ const formatAbstract = (item: Document) =>
const addAssetsToProject = async (projectName) => {
let projectId = '';
if (projectName !== undefined && typeof projectName.value === 'string') {
const project = projectsList.value.find((p) => p.name === projectName.value);
const project = useProjects().allProjects?.value?.find((p) => p.name === projectName.value);
projectId = project?.id as string;
} else {
if (!resources.activeProject) return;
projectId = resources.activeProject.id;
if (useProjects().activeProject.value) return;
projectId = useProjects().activeProject.value!.id;
}
addResourcesToProject(projectId);
emit('close');
};
onMounted(async () => {
const all = (await ProjectService.getAll()) as unknown as IProject[];
if (all !== null) {
projectsList.value = all;
}
});
</script>

<style scoped>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,17 @@

<script setup lang="ts">
import { ref, computed } from 'vue';
import { Project } from '@/types/Types';
import Button from 'primevue/button';
import Card from 'primevue/card';
import Menu from 'primevue/menu';
import Skeleton from 'primevue/skeleton';
import { formatDdMmmYyyy } from '@/utils/date';
import { placeholder } from '@/utils/project-card';
import DatasetIcon from '@/assets/svg/icons/dataset.svg?component';
import { IProject } from '@/types/Project';
const props = defineProps<{
project?: Project;
project?: IProject;
projectMenuItems?: any[];
}>();
Expand Down
Loading

0 comments on commit d375c5d

Please sign in to comment.