1
0
Fork 0
mirror of https://github.com/pawelmalak/flame.git synced 2025-07-23 21:29:37 +02:00

fix integrations

This commit is contained in:
François Darveau 2021-12-08 17:33:30 -05:00
parent e5154576b4
commit e7cd4d7705
21 changed files with 125 additions and 63 deletions

View file

@ -42,7 +42,7 @@ export const AppCard = (props: Props): JSX.Element => {
<div className={classes.Apps}>
{category.apps.map((app: App) => {
const redirectUrl = urlParser(app.url)[1];
const [displayUrl, redirectUrl] = urlParser(app.url);
let iconEl: JSX.Element = <Fragment></Fragment>;
@ -90,7 +90,10 @@ export const AppCard = (props: Props): JSX.Element => {
key={`app-${app.id}`}
>
{app.icon && iconEl}
{app.name}
<div className={classes.AppCardDetails}>
<h5>{app.name}</h5>
<span>{displayUrl}</span>
</div>
</a>
);
})}

View file

@ -1,6 +1,8 @@
import { useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import { Category } from '../../../interfaces';
import { State } from '../../../store/reducers';
import { Message } from '../../UI';
import { AppCard } from '../AppCard/AppCard';
import classes from './AppGrid.module.css';
@ -20,6 +22,10 @@ export const AppGrid = (props: Props): JSX.Element => {
fromHomepage = false,
} = props;
const {
config: { config }
} = useSelector((state: State) => state);
let apps: JSX.Element;
if (categories.length) {
@ -28,7 +34,7 @@ export const AppGrid = (props: Props): JSX.Element => {
} else {
apps = (
<div className={classes.AppGrid}>
{categories.map(
{categories.filter((category : Category) => !config.hideEmptyCategories || category.apps.length > 0).map(
(category: Category): JSX.Element => (
<AppCard
category={category}

View file

@ -30,16 +30,9 @@ export const Apps = (props: Props): JSX.Element => {
// Get Redux action creators
const dispatch = useDispatch();
const { getCategories, setEditCategory, setEditApp } =
const { setEditCategory, setEditApp } =
bindActionCreators(actionCreators, dispatch);
// Load categories if array is empty
useEffect(() => {
if (!categories.length) {
getCategories();
}
}, []);
// Form
const [modalIsOpen, setModalIsOpen] = useState(false);
const [formContentType, setFormContentType] = useState(ContentType.category);

View file

@ -1,6 +1,8 @@
import { useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import { Category } from '../../../interfaces';
import { State } from '../../../store/reducers';
import { Message } from '../../UI';
import { BookmarkCard } from '../BookmarkCard/BookmarkCard';
import classes from './BookmarkGrid.module.css';
@ -20,6 +22,10 @@ export const BookmarkGrid = (props: Props): JSX.Element => {
fromHomepage = false,
} = props;
const {
config: { config }
} = useSelector((state: State) => state);
let bookmarks: JSX.Element;
if (categories.length) {
@ -28,7 +34,7 @@ export const BookmarkGrid = (props: Props): JSX.Element => {
} else {
bookmarks = (
<div className={classes.BookmarkGrid}>
{categories.map(
{categories.filter((category : Category) => !config.hideEmptyCategories || category.apps.length > 0).map(
(category: Category): JSX.Element => (
<BookmarkCard
category={category}

View file

@ -30,16 +30,9 @@ export const Bookmarks = (props: Props): JSX.Element => {
// Get Redux action creators
const dispatch = useDispatch();
const { getCategories, setEditCategory, setEditBookmark } =
const { setEditCategory, setEditBookmark } =
bindActionCreators(actionCreators, dispatch);
// Load categories if array is empty
useEffect(() => {
if (!categories.length) {
getCategories();
}
}, []);
// Form
const [modalIsOpen, setModalIsOpen] = useState(false);
const [formContentType, setFormContentType] = useState(ContentType.category);

View file

@ -283,7 +283,7 @@ export const UISettings = (): JSX.Element => {
</select>
</InputGroup>
{/* HIDE CATEGORIES */}
{/* HIDE BOOKMARKS */}
<InputGroup>
<label htmlFor="hideBookmarks">Hide bookmarks</label>
<select
@ -297,6 +297,20 @@ export const UISettings = (): JSX.Element => {
</select>
</InputGroup>
{/* HIDE EMPTY CATEGORIES */}
<InputGroup>
<label htmlFor="hideEmptyCategories">Hide empty categories</label>
<select
id="hideEmptyCategories"
name="hideEmptyCategories"
value={formData.hideEmptyCategories ? 1 : 0}
onChange={(e) => inputChangeHandler(e, { isBool: true })}
>
<option value={1}>True</option>
<option value={0}>False</option>
</select>
</InputGroup>
<Button>Save changes</Button>
</form>
);

View file

@ -16,6 +16,7 @@ export interface Config {
searchSameTab: boolean;
hideApps: boolean;
hideBookmarks: boolean;
hideEmptyCategories: boolean;
hideSearch: boolean;
defaultSearchProvider: string;
dockerApps: boolean;

View file

@ -23,6 +23,7 @@ export interface OtherSettingsForm {
hideHeader: boolean;
hideApps: boolean;
hideBookmarks: boolean;
hideEmptyCategories: boolean;
useOrdering: string;
appsSameTab: boolean;
bookmarksSameTab: boolean;

View file

@ -5,8 +5,6 @@ import { Action } from '../actions';
import { categoriesReducer, CategoriesState } from './category';
interface AppsState extends CategoriesState {
loading: boolean;
errors: string | undefined;
categories: Category[];
categoryInEdit: Category | null;
appInEdit: App | null;

View file

@ -5,8 +5,6 @@ import { Action } from '../actions';
import { categoriesReducer, CategoriesState } from './category';
interface BookmarksState extends CategoriesState {
loading: boolean;
errors: string | undefined;
categories: Category[];
categoryInEdit: Category | null;
bookmarkInEdit: Bookmark | null;

View file

@ -16,6 +16,7 @@ export const configTemplate: Config = {
searchSameTab: false,
hideApps: false,
hideBookmarks: false,
hideEmptyCategories: true,
hideSearch: false,
defaultSearchProvider: 'l',
dockerApps: false,

View file

@ -8,6 +8,7 @@ export const otherSettingsTemplate: OtherSettingsForm = {
hideHeader: false,
hideApps: false,
hideBookmarks: false,
hideEmptyCategories: true,
useOrdering: 'createdAt',
appsSameTab: false,
bookmarksSameTab: false,

View file

@ -115,7 +115,7 @@ const useDocker = async (apps) => {
const icons = labels['flame.icon'] ? labels['flame.icon'].split(';') : [];
for (let i = 0; i < names.length; i++) {
const category = categoriesLabels[i] ? categories.find(category => category.name.toUpperCase() === categoriesLabels[i].toUpperCase()) : dockerDefaultCategory;
let category = categoriesLabels[i] ? categories.find(category => category.name.toUpperCase() === categoriesLabels[i].toUpperCase()) : dockerDefaultCategory;
if (!category) {
category = await createNewCategory(categoriesLabels[i]);
if (category) {
@ -129,7 +129,7 @@ const useDocker = async (apps) => {
name: names[i] || names[0],
url: urls[i] || urls[0],
icon: icons[i] || 'docker',
category: category.id,
categoryId: category.id,
orderId: orders[i] || 500,
});
}
@ -141,7 +141,6 @@ const useDocker = async (apps) => {
await app.update({ isPinned: false });
}
}
for (const item of dockerApps) {
// If app already exists, update it
if (apps.some((app) => app.name === item.name)) {

View file

@ -67,7 +67,7 @@ const useKubernetes = async (apps) => {
const icons = annotations['flame.pawelmalak/icon'] ? annotations['flame.pawelmalak/icon'].split(';') : [];
for (let i = 0; i < names.length; i++) {
const category = categoriesLabels[i] ? categories.find(category => category.name.toUpperCase() === categoriesLabels[i].toUpperCase()) : kubernetesDefaultCategory;
let category = categoriesLabels[i] ? categories.find(category => category.name.toUpperCase() === categoriesLabels[i].toUpperCase()) : kubernetesDefaultCategory;
if (!category) {
category = await createNewCategory(categoriesLabels[i]);
if (category) {
@ -81,7 +81,7 @@ const useKubernetes = async (apps) => {
name: names[i] || names[0],
url: urls[i] || urls[0],
icon: icons[i] || 'kubernetes',
category: category.id,
categoryId: category.id,
orderId: orders[i] || 500,
});
}

View file

@ -10,12 +10,11 @@ const { useKubernetes, useDocker } = require('./docker');
// @access Public
const getAllApps = asyncWrapper(async (req, res, next) => {
const {
useOrdering: orderType,
dockerApps: useDockerAPI,
kubernetesApps: useKubernetesAPI,
useOrdering: orderType
} = await loadConfig();
let apps = await loadIntegrationsApps();
// Load apps to create/update apps from integrations (Docker, Kubernetes, etc.)
await initIntegrationsApps();
// apps visibility
const where = req.isAuthenticated ? {} : { isPublic: true };
@ -44,26 +43,4 @@ const getAllApps = asyncWrapper(async (req, res, next) => {
});
});
const loadIntegrationsApps = asyncWrapper(async () => {
const {
dockerApps: useDockerAPI,
kubernetesApps: useKubernetesAPI,
} = await loadConfig();
let apps;
if (useDockerAPI) {
await useDocker(apps);
}
if (useKubernetesAPI) {
await useKubernetes(apps);
}
return apps;
});
module.exports = {
getAllApps,
loadIntegrationsApps
}
module.exports = getAllApps;

View file

@ -0,0 +1,42 @@
const asyncWrapper = require('../../middleware/asyncWrapper');
const App = require('../../models/App');
const { Sequelize } = require('sequelize');
const loadConfig = require('../../utils/loadConfig');
const { useKubernetes, useDocker } = require('./docker');
// @desc Get all apps
// @route GET /api/integrationsApps
// @access Public
const getIntegrationsApps = asyncWrapper(async (req, res, next) => {
const {
useOrdering: orderType,
dockerApps: useDockerAPI,
kubernetesApps: useKubernetesAPI,
} = await loadConfig();
let apps;
if (useDockerAPI) {
await useDocker(apps);
}
if (useKubernetesAPI) {
await useKubernetes(apps);
}
if (process.env.NODE_ENV === 'production') {
// Set header to fetch containers info every time
return res.status(200).setHeader('Cache-Control', 'no-store').json({
success: true,
data: apps,
});
}
res.status(200).json({
success: true,
data: apps,
});
});
module.exports = getIntegrationsApps;

View file

@ -4,5 +4,5 @@ module.exports = {
deleteApp: require('./deleteApp'),
updateApp: require('./updateApp'),
reorderApps: require('./reorderApps'),
getAllApps: require('./getAllApps').getAllApps,
getAllApps: require('./getAllApps'),
};

View file

@ -4,7 +4,7 @@ const App = require('../../models/App');
const Bookmark = require('../../models/Bookmark');
const { Sequelize } = require('sequelize');
const loadConfig = require('../../utils/loadConfig');
const loadIntegrationsApps = require('../apps/getAllApps').loadIntegrationsApps;
const initIntegrationsApps = require('../../utils/init/initIntegrationsApps');
// @desc Get all categories
// @route GET /api/categories
@ -12,8 +12,8 @@ const loadIntegrationsApps = require('../apps/getAllApps').loadIntegrationsApps;
const getAllCategories = asyncWrapper(async (req, res, next) => {
const { useOrdering: orderType } = await loadConfig();
// Load apps to create apps from integrations (Docker, Kubernetes, etc.)
await loadIntegrationsApps();
// Load apps to create/update apps from integrations (Docker, Kubernetes, etc.)
await initIntegrationsApps();
let categories;
let output;

View file

@ -13,6 +13,7 @@ const Sockets = require('./Sockets');
// Utils
const initApp = require('./utils/init');
const initIntegrationsApps = require('./utils/init/initIntegrationsApps');
const Logger = require('./utils/Logger');
const logger = new Logger();
@ -24,6 +25,9 @@ const logger = new Logger();
await connectDB();
await associateModels();
// Load apps to create/update apps from integrations (Docker, Kubernetes, etc.)
await initIntegrationsApps();
// Create server for Express API and WebSockets
const server = http.createServer();
server.on('request', api);

View file

@ -0,0 +1,24 @@
const { useKubernetes, useDocker } = require('../../controllers/apps/docker');
const asyncWrapper = require('../../middleware/asyncWrapper');
const loadConfig = require('../loadConfig');
const loadIntegrationsApps = asyncWrapper(async () => {
const {
dockerApps: useDockerAPI,
kubernetesApps: useKubernetesAPI,
} = await loadConfig();
let apps;
if (useDockerAPI) {
await useDocker(apps);
}
if (useKubernetesAPI) {
await useKubernetes(apps);
}
return apps;
});
module.exports = loadIntegrationsApps;

View file

@ -14,6 +14,7 @@
"searchSameTab": false,
"hideApps": false,
"hideBookmarks": false,
"hideEmptyCategories": true,
"hideSearch": false,
"defaultSearchProvider": "l",
"dockerApps": false,