import { ProjectService } from "./project-service/project-service";
import { LinkService } from "./link-service/link-service";
import { FavoriteService } from "./favorite-service/favorite-service";
-import { CommonResourceService } from "../common/api/common-resource-service";
-import { CollectionResource } from "../models/collection";
-import { Resource } from "../models/resource";
+ import { AxiosInstance } from "axios";
import { CollectionService } from "./collection-service/collection-service";
+ import Axios from "axios";
+import { CollectionFilesService } from "./collection-files-service/collection-files-service";
- export const authService = new AuthService(authClient, apiClient);
- export const groupsService = new GroupsService(apiClient);
- export const projectService = new ProjectService(apiClient);
- export const collectionService = new CollectionService(apiClient);
- export const collectionFilesService = new CollectionFilesService(collectionService);
- export const linkService = new LinkService(apiClient);
- export const favoriteService = new FavoriteService(linkService, groupsService);
+ export interface ServiceRepository {
+ apiClient: AxiosInstance;
+
+ authService: AuthService;
+ groupsService: GroupsService;
+ projectService: ProjectService;
+ linkService: LinkService;
+ favoriteService: FavoriteService;
- collectionService: CommonResourceService<Resource>;
++ collectionService: CollectionService;
++ collectionFilesService: CollectionFilesService;
+ }
+
+ export const createServices = (baseUrl: string): ServiceRepository => {
+ const apiClient = Axios.create();
+ apiClient.defaults.baseURL = `${baseUrl}/arvados/v1`;
+
+ const authService = new AuthService(apiClient, baseUrl);
+ const groupsService = new GroupsService(apiClient);
+ const projectService = new ProjectService(apiClient);
+ const linkService = new LinkService(apiClient);
+ const favoriteService = new FavoriteService(linkService, groupsService);
+ const collectionService = new CollectionService(apiClient);
++ const collectionFilesService = new CollectionFilesService(collectionService);
+
+ return {
+ apiClient,
+ authService,
+ groupsService,
+ projectService,
+ linkService,
+ favoriteService,
- collectionService
++ collectionService,
++ collectionFilesService
+ };
+ };
import { Dispatch } from "redux";
import { ResourceKind } from "../../models/resource";
import { CollectionResource } from "../../models/collection";
- import { collectionService, collectionFilesService } from "../../services/services";
+import { collectionPanelFilesAction } from "./collection-panel-files/collection-panel-files-actions";
+import { createTree } from "../../models/tree";
- import { mapManifestToCollectionFilesTree } from "../../services/collection-files-service/collection-manifest-mapper";
- import { parseKeepManifestText } from "../../services/collection-files-service/collection-manifest-parser";
+ import { RootState } from "../store";
+ import { ServiceRepository } from "../../services/services";
export const collectionPanelActions = unionize({
LOAD_COLLECTION: ofType<{ uuid: string, kind: ResourceKind }>(),
export type CollectionPanelAction = UnionOf<typeof collectionPanelActions>;
export const loadCollection = (uuid: string, kind: ResourceKind) =>
- (dispatch: Dispatch) => {
+ (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
dispatch(collectionPanelActions.LOAD_COLLECTION({ uuid, kind }));
- return collectionService
+ dispatch(collectionPanelFilesAction.SET_COLLECTION_FILES({ files: createTree() }));
+ return services.collectionService
.get(uuid)
.then(item => {
- dispatch(collectionPanelActions.LOAD_COLLECTION_SUCCESS({ item: item as CollectionResource }));
+ dispatch(collectionPanelActions.LOAD_COLLECTION_SUCCESS({ item }));
- return collectionFilesService.getFiles(item.uuid);
++ return services.collectionFilesService.getFiles(item.uuid);
+ })
+ .then(files => {
+ dispatch(collectionPanelFilesAction.SET_COLLECTION_FILES({ files }));
});
};
// SPDX-License-Identifier: AGPL-3.0
import { unionize, ofType, UnionOf } from "unionize";
--import { CommonResourceService } from "../../common/api/common-resource-service";
import { Dispatch } from "redux";
- import { apiClient } from "../../common/api/server-api";
import { Resource, ResourceKind } from "../../models/resource";
+ import { RootState } from "../store";
+ import { ServiceRepository } from "../../services/services";
export const detailsPanelActions = unionize({
TOGGLE_DETAILS_PANEL: ofType<{}>(),
export type DetailsPanelAction = UnionOf<typeof detailsPanelActions>;
export const loadDetails = (uuid: string, kind: ResourceKind) =>
- (dispatch: Dispatch) => {
- (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
++ async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
dispatch(detailsPanelActions.LOAD_DETAILS({ uuid, kind }));
- getService(kind)
- getService(services, kind)
-- .get(uuid)
-- .then(project => {
-- dispatch(detailsPanelActions.LOAD_DETAILS_SUCCESS({ item: project }));
-- });
++ const item = await getService(services, kind).get(uuid);
++ dispatch(detailsPanelActions.LOAD_DETAILS_SUCCESS({ item }));
};
- const getService = (kind: ResourceKind) => {
+ const getService = (services: ServiceRepository, kind: ResourceKind) => {
switch (kind) {
case ResourceKind.PROJECT:
- return new CommonResourceService(apiClient, "groups");
+ return services.projectService;
case ResourceKind.COLLECTION:
- return new CommonResourceService(apiClient, "collections");
+ return services.collectionService;
default:
- return new CommonResourceService(apiClient, "");
+ return services.projectService;
}
};
import { PROJECT_PANEL_ID } from "./project-panel/project-panel-action";
import { ProjectPanelMiddlewareService } from "./project-panel/project-panel-middleware-service";
import { FavoritePanelMiddlewareService } from "./favorite-panel/favorite-panel-middleware-service";
- import { CollectionCreatorState, collectionCreationReducer } from './collections/creator/collection-creator-reducer';
import { CollectionPanelState, collectionPanelReducer } from './collection-panel/collection-panel-reducer';
+import { DialogState, dialogReducer } from './dialog/dialog-reducer';
+ import { CollectionsState, collectionsReducer } from './collections/collections-reducer';
+ import { ServiceRepository } from "../services/services";
const composeEnhancers =
(process.env.NODE_ENV === 'development' &&
contextMenu: ContextMenuState;
favorites: FavoritesState;
snackbar: SnackbarState;
+ collectionPanelFiles: CollectionPanelFilesState;
+ dialog: DialogState;
}
- const rootReducer = combineReducers({
- auth: authReducer,
- projects: projectsReducer,
- collectionCreation: collectionCreationReducer,
- router: routerReducer,
- dataExplorer: dataExplorerReducer,
- sidePanel: sidePanelReducer,
- collectionPanel: collectionPanelReducer,
- detailsPanel: detailsPanelReducer,
- contextMenu: contextMenuReducer,
- form: formReducer,
- favorites: favoritesReducer,
- snackbar: snackbarReducer,
- collectionPanelFiles: collectionPanelFilesReducer,
- dialog: dialogReducer
- });
+ export type RootStore = Store<RootState, Action> & { dispatch: Dispatch<any> };
+
+ export function configureStore(history: History, services: ServiceRepository): RootStore {
- const rootReducer = combineReducers({
- auth: authReducer(services),
- projects: projectsReducer,
++ const rootReducer = combineReducers({
++ auth: authReducer(services),
++ projects: projectsReducer,
+ collections: collectionsReducer,
- router: routerReducer,
- dataExplorer: dataExplorerReducer,
- sidePanel: sidePanelReducer,
- collectionPanel: collectionPanelReducer,
- detailsPanel: detailsPanelReducer,
- contextMenu: contextMenuReducer,
- form: formReducer,
- favorites: favoritesReducer,
- snackbar: snackbarReducer,
- });
++ router: routerReducer,
++ dataExplorer: dataExplorerReducer,
++ sidePanel: sidePanelReducer,
++ collectionPanel: collectionPanelReducer,
++ detailsPanel: detailsPanelReducer,
++ contextMenu: contextMenuReducer,
++ form: formReducer,
++ favorites: favoritesReducer,
++ snackbar: snackbarReducer,
++ collectionPanelFiles: collectionPanelFilesReducer,
++ dialog: dialogReducer
++ });
- export function configureStore(history: History) {
const projectPanelMiddleware = dataExplorerMiddleware(
- new ProjectPanelMiddlewareService(PROJECT_PANEL_ID)
+ new ProjectPanelMiddlewareService(services, PROJECT_PANEL_ID)
);
const favoritePanelMiddleware = dataExplorerMiddleware(
- new FavoritePanelMiddlewareService(FAVORITE_PANEL_ID)
+ new FavoritePanelMiddlewareService(services, FAVORITE_PANEL_ID)
);
const middlewares: Middleware[] = [
import { RouteComponentProps } from 'react-router';
import { ArvadosTheme } from '../../common/custom-theme';
import { RootState } from '../../store/store';
- import { MoreOptionsIcon, CollectionIcon } from '../../components/icon/icon';
+ import { MoreOptionsIcon, CollectionIcon, CopyIcon } from '../../components/icon/icon';
import { DetailsAttribute } from '../../components/details-attribute/details-attribute';
import { CollectionResource } from '../../models/collection';
+import { CollectionPanelFiles } from '../../views-components/collection-panel-files/collection-panel-files';
+ import * as CopyToClipboard from 'react-copy-to-clipboard';
- type CssRules = 'card' | 'iconHeader';
+ type CssRules = 'card' | 'iconHeader' | 'tag' | 'copyIcon';
const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
card: {
import { CollectionPanel } from '../collection-panel/collection-panel';
import { loadCollection } from '../../store/collection-panel/collection-panel-action';
import { getCollectionUrl } from '../../models/collection';
+import { RemoveDialog } from '../../views-components/remove-dialog/remove-dialog';
+import { RenameDialog } from '../../views-components/rename-dialog/rename-dialog';
+ import { UpdateCollectionDialog } from '../../views-components/update-collection-dialog/update-collection-dialog.';
+ import { AuthService } from "../../services/auth-service/auth-service";
- const drawerWidth = 240;
- const appBarHeight = 100;
+ const DRAWER_WITDH = 240;
+ const APP_BAR_HEIGHT = 100;
type CssRules = 'root' | 'appBar' | 'drawerPaper' | 'content' | 'contentWrapper' | 'toolbar';
<Snackbar />
<CreateProjectDialog />
<CreateCollectionDialog />
+ <RemoveDialog />
+ <RenameDialog />
+ <UpdateCollectionDialog />
<CurrentTokenDialog
currentToken={this.props.currentToken}
open={this.state.isCurrentTokenDialogOpen}
version "10.5.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.2.tgz#f19f05314d5421fe37e74153254201a7bf00a707"
++"@types/react-copy-to-clipboard@4.2.5":
++ version "4.2.5"
++ resolved "https://registry.yarnpkg.com/@types/react-copy-to-clipboard/-/react-copy-to-clipboard-4.2.5.tgz#bda288b4256288676019b75ca86f1714bbd206d4"
++ dependencies:
++ "@types/react" "*"
++
"@types/react-dom@16.0.6":
version "16.0.6"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.0.6.tgz#f1a65a4e7be8ed5d123f8b3b9eacc913e35a1a3c"
version "0.1.1"
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
++copy-to-clipboard@^3:
++ version "3.0.8"
++ resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.0.8.tgz#f4e82f4a8830dce4666b7eb8ded0c9bcc313aba9"
++ dependencies:
++ toggle-selection "^1.0.3"
++
core-js@^1.0.0:
version "1.2.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
minimist "^1.2.0"
strip-json-comments "~2.0.1"
++react-copy-to-clipboard@5.0.1:
++ version "5.0.1"
++ resolved "https://registry.yarnpkg.com/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.1.tgz#8eae107bb400be73132ed3b6a7b4fb156090208e"
++ dependencies:
++ copy-to-clipboard "^3"
++ prop-types "^15.5.8"
++
react-dev-utils@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-5.0.1.tgz#1f396e161fe44b595db1b186a40067289bf06613"
regex-not "^1.0.2"
safe-regex "^1.1.0"
++toggle-selection@^1.0.3:
++ version "1.0.6"
++ resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
++
toposort@^1.0.0:
version "1.0.7"
resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029"