Skip to content

Commit

Permalink
Merge pull request #17 from baaalint/feat/projects-table
Browse files Browse the repository at this point in the history
feat(tables): add projects + data sources table
  • Loading branch information
baaalint authored Sep 10, 2024
2 parents 59b4e3c + 917d5ee commit 099cd22
Show file tree
Hide file tree
Showing 30 changed files with 2,053 additions and 60 deletions.
8 changes: 8 additions & 0 deletions ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { Provider as JotaiProvider } from 'jotai'
import { ChatHistoriesTablePage } from 'pages/ChatHistoriesPage'
import { ChatPage } from 'pages/ChatPage'
import { DataSourceTablePage } from 'pages/DataSourcesTablePage'
import { DatasetsTablePage } from 'pages/DatasetsTablePage'
import { LoginPage } from 'pages/LoginPage'
import { ModelsTablePage } from 'pages/ModelsTablePage'
import { ProjectsTablePage } from 'pages/ProjectsTablePage'
import { UsersTablePage } from 'pages/UsersTablePage'
import { RouterProvider, createBrowserRouter } from 'react-router-dom'

Expand All @@ -33,6 +37,10 @@ function App() {
path: '/admin/users',
element: <UsersTablePage />
},
{ path: '/admin/projects', element: <ProjectsTablePage /> },
{ path: '/admin/data-sources', element: <DataSourceTablePage /> },
{ path: '/admin/datasets', element: <DatasetsTablePage /> },
{ path: '/admin/models', element: <ModelsTablePage /> },
{
path: '/admin/histories',
element: <ChatHistoriesTablePage />
Expand Down
47 changes: 47 additions & 0 deletions ui/src/atoms/dataSources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2024 Iguazio
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Client from '@services/Api';
import { DataSource, DataSourceType } from '@shared/types/dataSource';
import { atom } from 'jotai';

export const dataSourcesAtom = atom<DataSource[]>([]);

export const dataSourcesLoadingAtom = atom<boolean>(false);

export const dataSourcesErrorAtom = atom<string | null>(null);


export const dataSourcesWithFetchAtom = atom(
(get) => get(dataSourcesAtom),
async (_get, set, projectName) => {
set(dataSourcesLoadingAtom, true);
set(dataSourcesErrorAtom, null);
try {
const dataSources = await Client.getDataSources(projectName as string);
const sortedDataSources = dataSources.data.sort((a: DataSource, b: DataSource) => {
const dateA = new Date(a.created as string);
const dateB = new Date(b.created as string);
return dateA.getTime() - dateB.getTime();
});
set(dataSourcesAtom, sortedDataSources);
} catch (error) {
set(dataSourcesErrorAtom, 'Failed to fetch dataSources');
} finally {
set(dataSourcesLoadingAtom, false);
}
}
);

export const selectedDataSourceAtom = atom<DataSource>({ name: '', description: '', labels: {}, owner_id: '', data_source_type: DataSourceType.OTHER, project_id: '' });
47 changes: 47 additions & 0 deletions ui/src/atoms/datasets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2024 Iguazio
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Client from '@services/Api';
import { Dataset } from '@shared/types/dataset';
import { atom } from 'jotai';

export const datasetsAtom = atom<Dataset[]>([]);

export const datasetsLoadingAtom = atom<boolean>(false);

export const datasetsErrorAtom = atom<string | null>(null);


export const datasetsWithFetchAtom = atom(
(get) => get(datasetsAtom),
async (_get, set, username) => {
set(datasetsLoadingAtom, true);
set(datasetsErrorAtom, null);
try {
const datasets = await Client.getDatasets(username as string);
const sortedDatasets = datasets.data.sort((a: Dataset, b: Dataset) => {
const dateA = new Date(a.created as string);
const dateB = new Date(b.created as string);
return dateA.getTime() - dateB.getTime();
});
set(datasetsAtom, sortedDatasets);
} catch (error) {
set(datasetsErrorAtom, 'Failed to fetch datasets');
} finally {
set(datasetsLoadingAtom, false);
}
}
);

export const selectedDatasetAtom = atom<Dataset>({ name: '', description: '', labels: {}, owner_id: '', project_id: '', path: '', task: '' });
1 change: 1 addition & 0 deletions ui/src/atoms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const publicUserAtom = atom<User>({});
export const usernameAtom = atom<string>('');
export const isTypingAtom = atom<boolean>(false);
export const canSendMessageAtom = atom<boolean>(true);
export const isMessageErrorAtom = atom<boolean>(false);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const selectedRowAtom = atom<any>({});
Expand Down
47 changes: 47 additions & 0 deletions ui/src/atoms/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2024 Iguazio
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Client from '@services/Api';
import { Model, ModelType } from '@shared/types/model';
import { atom } from 'jotai';

export const modelsAtom = atom<Model[]>([]);

export const modelsLoadingAtom = atom<boolean>(false);

export const modelsErrorAtom = atom<string | null>(null);


export const modelsWithFetchAtom = atom(
(get) => get(modelsAtom),
async (_get, set, username) => {
set(modelsLoadingAtom, true);
set(modelsErrorAtom, null);
try {
const models = await Client.getModels(username as string);
const sortedModels = models.data.sort((a: Model, b: Model) => {
const dateA = new Date(a.created as string);
const dateB = new Date(b.created as string);
return dateA.getTime() - dateB.getTime();
});
set(modelsAtom, sortedModels);
} catch (error) {
set(modelsErrorAtom, 'Failed to fetch models');
} finally {
set(modelsLoadingAtom, false);
}
}
);

export const selectedModelAtom = atom<Model>({ name: '', description: '', labels: {}, owner_id: '', project_id: '', model_type: ModelType.MODEL, base_model: '' });
39 changes: 39 additions & 0 deletions ui/src/atoms/projects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2024 Iguazio
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Client from '@services/Api';
import { Project } from '@shared/types/project';
import { atom } from 'jotai';

export const projectsAtom = atom<Project[]>([]);
export const projectsLoadingAtom = atom<boolean>(false);
export const projectsErrorAtom = atom<string | null>(null);


export const projectsWithFetchAtom = atom(
(get) => get(projectsAtom),
async (_get, set) => {
set(projectsLoadingAtom, true);
set(projectsErrorAtom, null);
try {
const projects = await Client.getProjects();
set(projectsAtom, projects.data);
} catch (error) {
set(projectsErrorAtom, 'Failed to fetch projects');
} finally {
set(projectsLoadingAtom, false);
}
}
);

98 changes: 98 additions & 0 deletions ui/src/components/feature/AddEditDataSourceModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2024 Iguazio
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { publicUserAtom } from '@atoms/index'
import {
Button,
FormControl,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay
} from '@chakra-ui/react'
import { DataSource, DataSourceType } from '@shared/types/dataSource'
import { useAtom } from 'jotai'
import React, { useEffect, useState } from 'react'

type DataSourceModalProps = {
isOpen: boolean
onClose: () => void
onSave: (dataSource: DataSource) => void
dataSource?: DataSource
}

const AddEditDataSourceModal: React.FC<DataSourceModalProps> = ({ isOpen, onClose, onSave, dataSource }) => {
const [publicUser] = useAtom(publicUserAtom)
const [formData, setFormData] = useState<DataSource>(
dataSource || {
name: '',
description: '',
owner_id: publicUser.uid as string,
project_id: '',
data_source_type: DataSourceType.OTHER
}
)
useEffect(() => {
if (dataSource) {
setFormData(dataSource)
}
}, [dataSource])

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target
setFormData({ ...formData, [name]: value })
}

const handleSubmit = () => {
onSave(formData)
onClose()
}

return (
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>
{dataSource?.uid ? 'Edit' : 'Add New'} {' DataSource'}
</ModalHeader>
<ModalCloseButton />
<ModalBody>
<FormControl id="name" mb={4}>
<FormLabel>Data Source Name</FormLabel>
<Input type="text" name="name" value={formData.name || ''} onChange={handleChange} />
</FormControl>
<FormControl id="description" mb={4}>
<FormLabel>Description</FormLabel>
<Input type="text" name="description" value={formData.description || ''} onChange={handleChange} />
</FormControl>
</ModalBody>
<ModalFooter>
<Button isDisabled={!formData.description || !formData.name} colorScheme="blue" mr={3} onClick={handleSubmit}>
{dataSource ? 'Save Changes' : 'Add DataSource'}
</Button>
<Button variant="ghost" onClick={onClose}>
Cancel
</Button>
</ModalFooter>
</ModalContent>
</Modal>
)
}

export default AddEditDataSourceModal
Loading

0 comments on commit 099cd22

Please sign in to comment.