Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

style(projects): cleanup files and organize imports #5229

Merged
merged 8 commits into from
Nov 7, 2024
40 changes: 27 additions & 13 deletions jsapp/js/projects/customViewRoute.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,43 @@
// Libraries
import React, {useState, useEffect} from 'react';
import {useParams} from 'react-router-dom';
import {observer} from 'mobx-react-lite';
import {toJS} from 'mobx';

// Partial components
import ProjectsFilter from './projectViews/projectsFilter';
import ProjectsFieldsSelector from './projectViews/projectsFieldsSelector';
import ViewSwitcher from './projectViews/viewSwitcher';
import ProjectsTable from 'js/projects/projectsTable/projectsTable';
import Button from 'js/components/common/button';
import ProjectQuickActionsEmpty from './projectsTable/projectQuickActionsEmpty';
import ProjectQuickActions from './projectsTable/projectQuickActions';
import LimitNotifications from 'js/components/usageLimits/limitNotifications.component';
import ProjectBulkActions from './projectsTable/projectBulkActions';

// Stores, hooks and utilities
import {notify} from 'js/utils';
import {handleApiFail, fetchPostUrl} from 'js/api';
import customViewStore from './customViewStore';
import projectViewsStore from './projectViews/projectViewsStore';

// Constants and types
import type {
ProjectsFilterDefinition,
ProjectFieldName,
} from './projectViews/constants';
import ProjectsFilter from './projectViews/projectsFilter';
import ProjectsFieldsSelector from './projectViews/projectsFieldsSelector';
import {
DEFAULT_VISIBLE_FIELDS,
DEFAULT_ORDERABLE_FIELDS,
} from './projectViews/constants';
import ViewSwitcher from './projectViews/viewSwitcher';
import ProjectsTable from 'js/projects/projectsTable/projectsTable';
import Button from 'js/components/common/button';
import customViewStore from './customViewStore';
import projectViewsStore from './projectViews/projectViewsStore';
import styles from './projectViews.module.scss';
import {toJS} from 'mobx';
import {ROOT_URL} from 'js/constants';
import ProjectQuickActionsEmpty from './projectsTable/projectQuickActionsEmpty';
import ProjectQuickActions from './projectsTable/projectQuickActions';
import LimitNotifications from 'js/components/usageLimits/limitNotifications.component';
import ProjectBulkActions from './projectsTable/projectBulkActions';

// Styles
import styles from './projectViews.module.scss';

/**
* Component responsible for rendering a custom project view route (`#/projects/<vid>`).
*/
function CustomViewRoute() {
const {viewUid} = useParams();

Expand Down Expand Up @@ -131,7 +143,9 @@ function CustomViewRoute() {
</div>
)}
</header>

<LimitNotifications useModal />

<ProjectsTable
assets={customView.assets}
isLoading={!customView.isFirstLoadComplete}
Expand Down
18 changes: 11 additions & 7 deletions jsapp/js/projects/customViewStore.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
// Libraries
import $ from 'jquery';
import isEqual from 'lodash.isequal';
import {makeAutoObservable, reaction} from 'mobx';

// Stores and utilities
import {handleApiFail} from 'js/api';
import {buildQueriesFromFilters} from './projectViews/utils';
import session from 'js/stores/session';
import searchBoxStore from 'js/components/header/searchBoxStore';

// Constants and types
import type {
AssetResponse,
ProjectViewAsset,
PaginatedResponse,
FailResponse,
} from 'js/dataInterface';
import {handleApiFail} from 'js/api';
import {DEFAULT_VISIBLE_FIELDS, PROJECT_FIELDS} from './projectViews/constants';
import type {
ProjectFieldName,
ProjectsFilterDefinition,
} from './projectViews/constants';
import {buildQueriesFromFilters} from './projectViews/utils';
import type {ProjectsTableOrder} from './projectsTable/projectsTable';
import session from 'js/stores/session';
import searchBoxStore from 'js/components/header/searchBoxStore';
import {COMMON_QUERIES} from 'js/constants';

const SAVE_DATA_NAME = 'project_views_settings';
Expand Down Expand Up @@ -95,7 +100,7 @@ class CustomViewStore {
viewUid: string,
baseUrl: string,
defaultVisibleFields: ProjectFieldName[],
includeTypeFilter: boolean = true,
includeTypeFilter = true,
) {
this.viewUid = viewUid;
this.baseUrl = baseUrl;
Expand Down Expand Up @@ -370,8 +375,7 @@ class CustomViewStore {
// Then we load the saved settings (if they exist)
if (
'email' in session.currentAccount &&
session.currentAccount.extra_details[SAVE_DATA_NAME] &&
session.currentAccount.extra_details[SAVE_DATA_NAME][this.viewUid]
session.currentAccount.extra_details[SAVE_DATA_NAME]?.[this.viewUid]
) {
const savedViewData =
session.currentAccount.extra_details[SAVE_DATA_NAME][this.viewUid];
Expand Down
54 changes: 34 additions & 20 deletions jsapp/js/projects/myProjectsRoute.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,48 @@
// Libraries
import React, {useState, useEffect} from 'react';
import {observer} from 'mobx-react-lite';
import type {
ProjectsFilterDefinition,
ProjectFieldName,
} from './projectViews/constants';
import {toJS} from 'mobx';
import Dropzone from 'react-dropzone';
import {useSearchParams} from 'react-router-dom';

// Partial components
import ProjectsFilter from './projectViews/projectsFilter';
import ProjectsFieldsSelector from './projectViews/projectsFieldsSelector';
import {
HOME_VIEW,
HOME_ORDERABLE_FIELDS,
HOME_DEFAULT_VISIBLE_FIELDS,
HOME_EXCLUDED_FIELDS,
} from './projectViews/constants';
import ViewSwitcher from './projectViews/viewSwitcher';
import ProjectsTable from 'js/projects/projectsTable/projectsTable';
import customViewStore from './customViewStore';
import styles from './projectViews.module.scss';
import routeStyles from './myProjectsRoute.module.scss';
import {toJS} from 'mobx';
import {ROOT_URL} from 'js/constants';
import ProjectQuickActionsEmpty from './projectsTable/projectQuickActionsEmpty';
import ProjectQuickActions from './projectsTable/projectQuickActions';
import ProjectBulkActions from './projectsTable/projectBulkActions';
import Dropzone from 'react-dropzone';
import {validFileTypes} from 'js/utils';
import Icon from 'js/components/common/icon';
import {dropImportXLSForms} from 'js/dropzone.utils';
import LimitNotifications from 'js/components/usageLimits/limitNotifications.component';
import {useSearchParams} from 'react-router-dom';
import TransferProjectsInvite from 'js/components/permissions/transferProjects/transferProjectsInvite.component';
import Button from 'js/components/common/button';

// Stores, hooks and utilities
import customViewStore from './customViewStore';
import {validFileTypes} from 'js/utils';
import {dropImportXLSForms} from 'js/dropzone.utils';
import {
isInviteForLoggedInUser,
TransferStatuses,
} from 'js/components/permissions/transferProjects/transferProjects.api';
import Button from '../components/common/button';

// Constants and types
import type {
ProjectsFilterDefinition,
ProjectFieldName,
} from './projectViews/constants';
import {
HOME_VIEW,
HOME_ORDERABLE_FIELDS,
HOME_DEFAULT_VISIBLE_FIELDS,
HOME_EXCLUDED_FIELDS,
} from './projectViews/constants';
import {ROOT_URL} from 'js/constants';

// Styles
import styles from './projectViews.module.scss';
import routeStyles from './myProjectsRoute.module.scss';

interface InviteState {
valid: boolean;
Expand All @@ -43,6 +52,9 @@ interface InviteState {
currentOwner: string;
}

/**
* Component responsible for rendering "My projects" route (`#/projects/home`).
*/
function MyProjectsRoute() {
const [customView] = useState(customViewStore);
const [selectedRows, setSelectedRows] = useState<string[]>([]);
Expand Down Expand Up @@ -210,6 +222,7 @@ function MyProjectsRoute() {
</div>
)}
</header>

<ProjectsTable
assets={customView.assets}
isLoading={!customView.isFirstLoadComplete}
Expand All @@ -224,6 +237,7 @@ function MyProjectsRoute() {
selectedRows={selectedRows}
onRowsSelected={setSelectedRows}
/>

{invite.valid && invite.uid !== '' && (
<TransferProjectsInvite
setInvite={setInviteDetail}
Expand Down
9 changes: 8 additions & 1 deletion jsapp/js/projects/projectViews/projectsFieldsSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
// Libraries
import React, {useState, useEffect} from 'react';

// Partial components
import Button from 'js/components/common/button';
import type {MultiCheckboxItem} from 'js/components/common/multiCheckbox';
import MultiCheckbox from 'js/components/common/multiCheckbox';
import KoboModal from 'js/components/modals/koboModal';
import KoboModalHeader from 'js/components/modals/koboModalHeader';
import KoboModalContent from 'js/components/modals/koboModalContent';
import KoboModalFooter from 'js/components/modals/koboModalFooter';

// Constants and types
import type {MultiCheckboxItem} from 'js/components/common/multiCheckbox';
import type {ProjectFieldName} from './constants';
import {PROJECT_FIELDS, DEFAULT_VISIBLE_FIELDS} from './constants';

// Styles
import styles from './projectsFieldsSelector.module.scss';

interface ProjectsFieldsSelectorProps {
Expand Down
11 changes: 10 additions & 1 deletion jsapp/js/projects/projectViews/projectsFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
// Libraries
import React, {useState} from 'react';
import cx from 'classnames';
import clonedeep from 'lodash.clonedeep';

// Partial components
import Button from 'js/components/common/button';
import KoboModal from 'js/components/modals/koboModal';
import KoboModalHeader from 'js/components/modals/koboModalHeader';
import type {ProjectFieldName, ProjectsFilterDefinition} from './constants';
import ProjectsFilterEditor from './projectsFilterEditor';

// Utilities
import {removeIncorrectFilters} from './utils';

// Constants and types
import type {ProjectFieldName, ProjectsFilterDefinition} from './constants';

// Styles
import styles from './projectsFilter.module.scss';

// If there are "many" filters being displayed, we want the modal content to be
Expand Down
13 changes: 11 additions & 2 deletions jsapp/js/projects/projectViews/projectsFilterEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
// Libraries
import React from 'react';

// Partial components
import Button from 'js/components/common/button';
import TextBox from 'js/components/common/textBox';
import KoboSelect from 'js/components/common/koboSelect';

// Stores and utilities
import {generateUuid} from 'js/utils';
import {isFilterConditionValueRequired} from './utils';
import envStore from 'js/envStore';

// Constants and types
import type {
FilterConditionName,
ProjectFieldName,
ProjectsFilterDefinition,
} from './constants';
import {FILTER_CONDITIONS, PROJECT_FIELDS} from './constants';
import {isFilterConditionValueRequired} from './utils';
import envStore from 'js/envStore';

// Styles
import styles from './projectsFilterEditor.module.scss';

interface ProjectsFilterEditorProps {
Expand Down
29 changes: 24 additions & 5 deletions jsapp/js/projects/projectViews/viewSwitcher.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
// Libraries
import React, {useState} from 'react';
import {useNavigate} from 'react-router-dom';
import {observer} from 'mobx-react-lite';
import classNames from 'classnames';
import cx from 'classnames';

// Partial components
import Icon from 'js/components/common/icon';
import KoboDropdown from 'js/components/common/koboDropdown';
import {PROJECTS_ROUTES} from 'jsapp/js/router/routerConstants';

// Stores
import projectViewsStore from './projectViewsStore';
import styles from './viewSwitcher.module.scss';

// Constants
import {PROJECTS_ROUTES} from 'js/router/routerConstants';
import {HOME_VIEW} from './constants';

// Styles
import styles from './viewSwitcher.module.scss';

interface ViewSwitcherProps {
selectedViewUid: string;
}

/**
* A component that displays a view selector or just "My projects" text. What
* options are available depends on multiple factors: belonging to MMO
* organization, custom views being defined and user having permission to view
* them.
*/
function ViewSwitcher(props: ViewSwitcherProps) {
// We track the menu visibility for the trigger icon.
const [isMenuVisible, setIsMenuVisible] = useState(false);
Expand Down Expand Up @@ -45,7 +60,7 @@ function ViewSwitcher(props: ViewSwitcherProps) {
if (projectViews.views.length === 0) {
return (
<button
className={classNames(styles.trigger, styles.triggerSimple)}
className={cx(styles.trigger, styles.triggerSimple)}
title={triggerLabel}
>
<label>{triggerLabel}</label>
Expand All @@ -55,7 +70,7 @@ function ViewSwitcher(props: ViewSwitcherProps) {

return (
<div
className={classNames({
className={cx({
[styles.root]: true,
[styles.isMenuVisible]: isMenuVisible,
})}
Expand All @@ -73,13 +88,17 @@ function ViewSwitcher(props: ViewSwitcherProps) {
}
menuContent={
<div className={styles.menu}>
{/* This is the "My projects" option - always there */}
<button
key={HOME_VIEW.uid}
className={styles.menuOption}
onClick={() => onOptionClick(HOME_VIEW.uid)}
>
{HOME_VIEW.name}
</button>

{/* This is the list of all options for custom views. These are only
being added if custom views are defined (at least one). */}
{projectViews.views.map((view) => (
<button
key={view.uid}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
// Libraries
import React, {useState} from 'react';
import {fetchPost, handleApiFail} from 'js/api';
import {notify} from 'js/utils';

// Partial components
import KoboPrompt from 'js/components/modals/koboPrompt';
import Checkbox from 'js/components/common/checkbox';
import styles from './bulkDeletePrompt.module.scss';

// Stores, hooks and utilities
import {fetchPost, handleApiFail} from 'js/api';
import {notify} from 'js/utils';
import customViewStore from 'js/projects/customViewStore';
import {searches} from 'js/searches';

// Styles
import styles from './bulkDeletePrompt.module.scss';

type AssetsBulkAction = 'archive' | 'delete' | 'unarchive';
interface AssetsBulkResponse {
detail: string;
Expand Down
Loading
Loading