diff --git a/README.md b/README.md
index dadb428..669b7b0 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,7 @@ git clone https://github.com/pawelmalak/flame
cd flame
# run only once
-npm run dev-init
+npm run dev:init
# start backend and frontend development servers
npm run dev
diff --git a/client/src/components/Apps/AppGrid/AppGrid.tsx b/client/src/components/Apps/AppGrid/AppGrid.tsx
index cacc19c..30d5c8c 100644
--- a/client/src/components/Apps/AppGrid/AppGrid.tsx
+++ b/client/src/components/Apps/AppGrid/AppGrid.tsx
@@ -7,6 +7,7 @@ import AppCard from '../AppCard/AppCard';
interface ComponentProps {
apps: App[];
totalApps?: number;
+ searching: boolean;
}
const AppGrid = (props: ComponentProps): JSX.Element => {
@@ -16,26 +17,37 @@ const AppGrid = (props: ComponentProps): JSX.Element => {
apps = (
{props.apps.map((app: App): JSX.Element => {
- return
+ return
;
})}
- )
+ );
} else {
if (props.totalApps) {
- apps = (
- There are no pinned applications. You can pin them from the /applications menu
- );
+ if (props.searching) {
+ apps = (
+
+ No apps match your search criteria
+
+ );
+ } else {
+ apps = (
+
+ There are no pinned applications. You can pin them from the{' '}
+ /applications menu
+
+ );
+ }
} else {
apps = (
- You don't have any applications. You can add a new one from /applications menu
+
+ You don't have any applications. You can add a new one from{' '}
+ /applications menu
+
);
}
}
return apps;
-}
+};
-export default AppGrid;
\ No newline at end of file
+export default AppGrid;
diff --git a/client/src/components/Apps/Apps.tsx b/client/src/components/Apps/Apps.tsx
index 88c3fff..751a196 100644
--- a/client/src/components/Apps/Apps.tsx
+++ b/client/src/components/Apps/Apps.tsx
@@ -27,14 +27,11 @@ interface ComponentProps {
getApps: Function;
apps: App[];
loading: boolean;
+ searching: boolean;
}
const Apps = (props: ComponentProps): JSX.Element => {
- const {
- getApps,
- apps,
- loading
- } = props;
+ const { getApps, apps, loading, searching = false } = props;
const [modalIsOpen, setModalIsOpen] = useState(false);
const [isInEdit, setIsInEdit] = useState(false);
@@ -47,8 +44,8 @@ const Apps = (props: ComponentProps): JSX.Element => {
orderId: 0,
id: 0,
createdAt: new Date(),
- updatedAt: new Date()
- })
+ updatedAt: new Date(),
+ });
useEffect(() => {
if (apps.length === 0) {
@@ -59,63 +56,57 @@ const Apps = (props: ComponentProps): JSX.Element => {
const toggleModal = (): void => {
setModalIsOpen(!modalIsOpen);
setIsInUpdate(false);
- }
+ };
const toggleEdit = (): void => {
setIsInEdit(!isInEdit);
setIsInUpdate(false);
- }
+ };
const toggleUpdate = (app: App): void => {
setAppInUpdate(app);
setIsInUpdate(true);
setModalIsOpen(true);
- }
+ };
return (
- {!isInUpdate
- ?
- :
- }
+ {!isInUpdate ? (
+
+ ) : (
+
+ )}
Go back)}
+ title="All Applications"
+ subtitle={Go back}
/>
-
+
- {loading
- ?
- : (!isInEdit
- ?
- :
)
- }
+ {loading ? (
+
+ ) : !isInEdit ? (
+
+ ) : (
+
+ )}
- )
-}
+ );
+};
const mapStateToProps = (state: GlobalState) => {
return {
apps: state.app.apps,
- loading: state.app.loading
- }
-}
+ loading: state.app.loading,
+ };
+};
-export default connect(mapStateToProps, { getApps })(Apps);
\ No newline at end of file
+export default connect(mapStateToProps, { getApps })(Apps);
diff --git a/client/src/components/Home/Home.tsx b/client/src/components/Home/Home.tsx
index ece4a8a..12097bf 100644
--- a/client/src/components/Home/Home.tsx
+++ b/client/src/components/Home/Home.tsx
@@ -47,13 +47,16 @@ const Home = (props: ComponentProps): JSX.Element => {
appsLoading,
getCategories,
categories,
- categoriesLoading
+ categoriesLoading,
} = props;
const [header, setHeader] = useState({
dateTime: dateTime(),
- greeting: greeter()
- })
+ greeting: greeter(),
+ });
+
+ // Local search query
+ const [localSearch, setLocalSearch] = useState(null);
// Load applications
useEffect(() => {
@@ -78,78 +81,93 @@ const Home = (props: ComponentProps): JSX.Element => {
interval = setInterval(() => {
setHeader({
dateTime: dateTime(),
- greeting: greeter()
- })
+ greeting: greeter(),
+ });
}, 1000);
}
return () => clearInterval(interval);
- }, [])
-
+ }, []);
+
return (
- {searchConfig('hideSearch', 0) !== 1
- ?
- :
- }
+ {searchConfig('hideSearch', 0) !== 1 ? (
+
+ ) : (
+
+ )}
- {searchConfig('hideHeader', 0) !== 1
- ? (
-
- {header.dateTime}
- Go to Settings
-
- {header.greeting}
-
-
-
- )
- :
- }
-
- {searchConfig('hideApps', 0) !== 1
- ? (
-
- {appsLoading
- ?
- : app.isPinned)}
- totalApps={apps.length}
- />
- }
-
- )
- :
- }
+ {searchConfig('hideHeader', 0) !== 1 ? (
+
+ {header.dateTime}
+
+ Go to Settings
+
+
+ {header.greeting}
+
+
+
+ ) : (
+
+ )}
- {searchConfig('hideCategories', 0) !== 1
- ? (
-
- {categoriesLoading
- ?
- : category.isPinned)}
- totalCategories={categories.length}
- />
- }
- )
- :
- }
+ {searchConfig('hideApps', 0) !== 1 ? (
+
+
+ {appsLoading ? (
+
+ ) : (
+ isPinned)
+ : apps.filter(({ name }) =>
+ new RegExp(localSearch, 'i').test(name)
+ )
+ }
+ totalApps={apps.length}
+ searching={!!localSearch}
+ />
+ )}
+
+
+ ) : (
+
+ )}
-
-
+ {searchConfig('hideCategories', 0) !== 1 ? (
+
+
+ {categoriesLoading ? (
+
+ ) : (
+ category.isPinned
+ )}
+ totalCategories={categories.length}
+ />
+ )}
+
+ ) : (
+
+ )}
+
+
+
- )
-}
+ );
+};
const mapStateToProps = (state: GlobalState) => {
return {
appsLoading: state.app.loading,
apps: state.app.apps,
categoriesLoading: state.bookmark.loading,
- categories: state.bookmark.categories
- }
-}
+ categories: state.bookmark.categories,
+ };
+};
-export default connect(mapStateToProps, { getApps, getCategories })(Home);
\ No newline at end of file
+export default connect(mapStateToProps, { getApps, getCategories })(Home);
diff --git a/client/src/components/SearchBar/SearchBar.tsx b/client/src/components/SearchBar/SearchBar.tsx
index 029f175..0b5f3cc 100644
--- a/client/src/components/SearchBar/SearchBar.tsx
+++ b/client/src/components/SearchBar/SearchBar.tsx
@@ -15,36 +15,41 @@ import { searchParser } from '../../utility';
interface ComponentProps {
createNotification: (notification: NewNotification) => void;
+ setLocalSearch: (query: string) => void;
}
const SearchBar = (props: ComponentProps): JSX.Element => {
+ const { setLocalSearch, createNotification } = props;
+
const inputRef = useRef(document.createElement('input'));
useEffect(() => {
inputRef.current.focus();
- }, [])
+ }, []);
const searchHandler = (e: KeyboardEvent) => {
if (e.code === 'Enter') {
- const prefixFound = searchParser(inputRef.current.value);
+ const searchResult = searchParser(inputRef.current.value);
- if (!prefixFound) {
- props.createNotification({
+ if (!searchResult.prefix) {
+ createNotification({
title: 'Error',
- message: 'Prefix not found'
- })
+ message: 'Prefix not found',
+ });
+ } else if (searchResult.isLocal) {
+ setLocalSearch(searchResult.query);
}
}
- }
+ };
return (
searchHandler(e)}
/>
- )
-}
+ );
+};
-export default connect(null, { createNotification })(SearchBar);
\ No newline at end of file
+export default connect(null, { createNotification })(SearchBar);
diff --git a/client/src/components/Settings/OtherSettings/OtherSettings.tsx b/client/src/components/Settings/OtherSettings/OtherSettings.tsx
index 31bbd52..afaf072 100644
--- a/client/src/components/Settings/OtherSettings/OtherSettings.tsx
+++ b/client/src/components/Settings/OtherSettings/OtherSettings.tsx
@@ -6,7 +6,7 @@ import {
createNotification,
updateConfig,
sortApps,
- sortCategories
+ sortCategories,
} from '../../../store/actions';
// Typescript
@@ -14,7 +14,7 @@ import {
GlobalState,
NewNotification,
Query,
- SettingsForm
+ SettingsForm,
} from '../../../interfaces';
// UI
@@ -53,7 +53,7 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
searchSameTab: 0,
dockerApps: 1,
kubernetesApps: 1,
- unpinStoppedApps: 1
+ unpinStoppedApps: 1,
});
// Get config
@@ -73,7 +73,7 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
searchSameTab: searchConfig('searchSameTab', 0),
dockerApps: searchConfig('dockerApps', 0),
kubernetesApps: searchConfig('kubernetesApps', 0),
- unpinStoppedApps: searchConfig('unpinStoppedApps', 0)
+ unpinStoppedApps: searchConfig('unpinStoppedApps', 0),
});
}, [props.loading]);
@@ -105,115 +105,117 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
setFormData({
...formData,
- [e.target.name]: value
+ [e.target.name]: value,
});
};
return (
-