mirror of
https://github.com/pawelmalak/flame.git
synced 2025-07-23 21:29:37 +02:00
fix integrations
This commit is contained in:
parent
e5154576b4
commit
e7cd4d7705
21 changed files with 125 additions and 63 deletions
|
@ -42,7 +42,7 @@ export const AppCard = (props: Props): JSX.Element => {
|
||||||
|
|
||||||
<div className={classes.Apps}>
|
<div className={classes.Apps}>
|
||||||
{category.apps.map((app: App) => {
|
{category.apps.map((app: App) => {
|
||||||
const redirectUrl = urlParser(app.url)[1];
|
const [displayUrl, redirectUrl] = urlParser(app.url);
|
||||||
|
|
||||||
let iconEl: JSX.Element = <Fragment></Fragment>;
|
let iconEl: JSX.Element = <Fragment></Fragment>;
|
||||||
|
|
||||||
|
@ -89,8 +89,11 @@ export const AppCard = (props: Props): JSX.Element => {
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
key={`app-${app.id}`}
|
key={`app-${app.id}`}
|
||||||
>
|
>
|
||||||
{app.icon && iconEl}
|
{app.icon && iconEl}
|
||||||
{app.name}
|
<div className={classes.AppCardDetails}>
|
||||||
|
<h5>{app.name}</h5>
|
||||||
|
<span>{displayUrl}</span>
|
||||||
|
</div>
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import { Category } from '../../../interfaces';
|
import { Category } from '../../../interfaces';
|
||||||
|
import { State } from '../../../store/reducers';
|
||||||
import { Message } from '../../UI';
|
import { Message } from '../../UI';
|
||||||
import { AppCard } from '../AppCard/AppCard';
|
import { AppCard } from '../AppCard/AppCard';
|
||||||
import classes from './AppGrid.module.css';
|
import classes from './AppGrid.module.css';
|
||||||
|
@ -20,6 +22,10 @@ export const AppGrid = (props: Props): JSX.Element => {
|
||||||
fromHomepage = false,
|
fromHomepage = false,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const {
|
||||||
|
config: { config }
|
||||||
|
} = useSelector((state: State) => state);
|
||||||
|
|
||||||
let apps: JSX.Element;
|
let apps: JSX.Element;
|
||||||
|
|
||||||
if (categories.length) {
|
if (categories.length) {
|
||||||
|
@ -28,7 +34,7 @@ export const AppGrid = (props: Props): JSX.Element => {
|
||||||
} else {
|
} else {
|
||||||
apps = (
|
apps = (
|
||||||
<div className={classes.AppGrid}>
|
<div className={classes.AppGrid}>
|
||||||
{categories.map(
|
{categories.filter((category : Category) => !config.hideEmptyCategories || category.apps.length > 0).map(
|
||||||
(category: Category): JSX.Element => (
|
(category: Category): JSX.Element => (
|
||||||
<AppCard
|
<AppCard
|
||||||
category={category}
|
category={category}
|
||||||
|
|
|
@ -30,16 +30,9 @@ export const Apps = (props: Props): JSX.Element => {
|
||||||
|
|
||||||
// Get Redux action creators
|
// Get Redux action creators
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { getCategories, setEditCategory, setEditApp } =
|
const { setEditCategory, setEditApp } =
|
||||||
bindActionCreators(actionCreators, dispatch);
|
bindActionCreators(actionCreators, dispatch);
|
||||||
|
|
||||||
// Load categories if array is empty
|
|
||||||
useEffect(() => {
|
|
||||||
if (!categories.length) {
|
|
||||||
getCategories();
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Form
|
// Form
|
||||||
const [modalIsOpen, setModalIsOpen] = useState(false);
|
const [modalIsOpen, setModalIsOpen] = useState(false);
|
||||||
const [formContentType, setFormContentType] = useState(ContentType.category);
|
const [formContentType, setFormContentType] = useState(ContentType.category);
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import { Category } from '../../../interfaces';
|
import { Category } from '../../../interfaces';
|
||||||
|
import { State } from '../../../store/reducers';
|
||||||
import { Message } from '../../UI';
|
import { Message } from '../../UI';
|
||||||
import { BookmarkCard } from '../BookmarkCard/BookmarkCard';
|
import { BookmarkCard } from '../BookmarkCard/BookmarkCard';
|
||||||
import classes from './BookmarkGrid.module.css';
|
import classes from './BookmarkGrid.module.css';
|
||||||
|
@ -20,6 +22,10 @@ export const BookmarkGrid = (props: Props): JSX.Element => {
|
||||||
fromHomepage = false,
|
fromHomepage = false,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const {
|
||||||
|
config: { config }
|
||||||
|
} = useSelector((state: State) => state);
|
||||||
|
|
||||||
let bookmarks: JSX.Element;
|
let bookmarks: JSX.Element;
|
||||||
|
|
||||||
if (categories.length) {
|
if (categories.length) {
|
||||||
|
@ -28,7 +34,7 @@ export const BookmarkGrid = (props: Props): JSX.Element => {
|
||||||
} else {
|
} else {
|
||||||
bookmarks = (
|
bookmarks = (
|
||||||
<div className={classes.BookmarkGrid}>
|
<div className={classes.BookmarkGrid}>
|
||||||
{categories.map(
|
{categories.filter((category : Category) => !config.hideEmptyCategories || category.apps.length > 0).map(
|
||||||
(category: Category): JSX.Element => (
|
(category: Category): JSX.Element => (
|
||||||
<BookmarkCard
|
<BookmarkCard
|
||||||
category={category}
|
category={category}
|
||||||
|
|
|
@ -30,16 +30,9 @@ export const Bookmarks = (props: Props): JSX.Element => {
|
||||||
|
|
||||||
// Get Redux action creators
|
// Get Redux action creators
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { getCategories, setEditCategory, setEditBookmark } =
|
const { setEditCategory, setEditBookmark } =
|
||||||
bindActionCreators(actionCreators, dispatch);
|
bindActionCreators(actionCreators, dispatch);
|
||||||
|
|
||||||
// Load categories if array is empty
|
|
||||||
useEffect(() => {
|
|
||||||
if (!categories.length) {
|
|
||||||
getCategories();
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Form
|
// Form
|
||||||
const [modalIsOpen, setModalIsOpen] = useState(false);
|
const [modalIsOpen, setModalIsOpen] = useState(false);
|
||||||
const [formContentType, setFormContentType] = useState(ContentType.category);
|
const [formContentType, setFormContentType] = useState(ContentType.category);
|
||||||
|
|
|
@ -283,7 +283,7 @@ export const UISettings = (): JSX.Element => {
|
||||||
</select>
|
</select>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
|
||||||
{/* HIDE CATEGORIES */}
|
{/* HIDE BOOKMARKS */}
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<label htmlFor="hideBookmarks">Hide bookmarks</label>
|
<label htmlFor="hideBookmarks">Hide bookmarks</label>
|
||||||
<select
|
<select
|
||||||
|
@ -297,6 +297,20 @@ export const UISettings = (): JSX.Element => {
|
||||||
</select>
|
</select>
|
||||||
</InputGroup>
|
</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>
|
<Button>Save changes</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|
|
@ -16,6 +16,7 @@ export interface Config {
|
||||||
searchSameTab: boolean;
|
searchSameTab: boolean;
|
||||||
hideApps: boolean;
|
hideApps: boolean;
|
||||||
hideBookmarks: boolean;
|
hideBookmarks: boolean;
|
||||||
|
hideEmptyCategories: boolean;
|
||||||
hideSearch: boolean;
|
hideSearch: boolean;
|
||||||
defaultSearchProvider: string;
|
defaultSearchProvider: string;
|
||||||
dockerApps: boolean;
|
dockerApps: boolean;
|
||||||
|
|
|
@ -23,6 +23,7 @@ export interface OtherSettingsForm {
|
||||||
hideHeader: boolean;
|
hideHeader: boolean;
|
||||||
hideApps: boolean;
|
hideApps: boolean;
|
||||||
hideBookmarks: boolean;
|
hideBookmarks: boolean;
|
||||||
|
hideEmptyCategories: boolean;
|
||||||
useOrdering: string;
|
useOrdering: string;
|
||||||
appsSameTab: boolean;
|
appsSameTab: boolean;
|
||||||
bookmarksSameTab: boolean;
|
bookmarksSameTab: boolean;
|
||||||
|
|
|
@ -5,8 +5,6 @@ import { Action } from '../actions';
|
||||||
import { categoriesReducer, CategoriesState } from './category';
|
import { categoriesReducer, CategoriesState } from './category';
|
||||||
|
|
||||||
interface AppsState extends CategoriesState {
|
interface AppsState extends CategoriesState {
|
||||||
loading: boolean;
|
|
||||||
errors: string | undefined;
|
|
||||||
categories: Category[];
|
categories: Category[];
|
||||||
categoryInEdit: Category | null;
|
categoryInEdit: Category | null;
|
||||||
appInEdit: App | null;
|
appInEdit: App | null;
|
||||||
|
|
|
@ -5,8 +5,6 @@ import { Action } from '../actions';
|
||||||
import { categoriesReducer, CategoriesState } from './category';
|
import { categoriesReducer, CategoriesState } from './category';
|
||||||
|
|
||||||
interface BookmarksState extends CategoriesState {
|
interface BookmarksState extends CategoriesState {
|
||||||
loading: boolean;
|
|
||||||
errors: string | undefined;
|
|
||||||
categories: Category[];
|
categories: Category[];
|
||||||
categoryInEdit: Category | null;
|
categoryInEdit: Category | null;
|
||||||
bookmarkInEdit: Bookmark | null;
|
bookmarkInEdit: Bookmark | null;
|
||||||
|
|
|
@ -16,6 +16,7 @@ export const configTemplate: Config = {
|
||||||
searchSameTab: false,
|
searchSameTab: false,
|
||||||
hideApps: false,
|
hideApps: false,
|
||||||
hideBookmarks: false,
|
hideBookmarks: false,
|
||||||
|
hideEmptyCategories: true,
|
||||||
hideSearch: false,
|
hideSearch: false,
|
||||||
defaultSearchProvider: 'l',
|
defaultSearchProvider: 'l',
|
||||||
dockerApps: false,
|
dockerApps: false,
|
||||||
|
|
|
@ -8,6 +8,7 @@ export const otherSettingsTemplate: OtherSettingsForm = {
|
||||||
hideHeader: false,
|
hideHeader: false,
|
||||||
hideApps: false,
|
hideApps: false,
|
||||||
hideBookmarks: false,
|
hideBookmarks: false,
|
||||||
|
hideEmptyCategories: true,
|
||||||
useOrdering: 'createdAt',
|
useOrdering: 'createdAt',
|
||||||
appsSameTab: false,
|
appsSameTab: false,
|
||||||
bookmarksSameTab: false,
|
bookmarksSameTab: false,
|
||||||
|
|
|
@ -115,7 +115,7 @@ const useDocker = async (apps) => {
|
||||||
const icons = labels['flame.icon'] ? labels['flame.icon'].split(';') : [];
|
const icons = labels['flame.icon'] ? labels['flame.icon'].split(';') : [];
|
||||||
|
|
||||||
for (let i = 0; i < names.length; i++) {
|
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) {
|
if (!category) {
|
||||||
category = await createNewCategory(categoriesLabels[i]);
|
category = await createNewCategory(categoriesLabels[i]);
|
||||||
if (category) {
|
if (category) {
|
||||||
|
@ -129,7 +129,7 @@ const useDocker = async (apps) => {
|
||||||
name: names[i] || names[0],
|
name: names[i] || names[0],
|
||||||
url: urls[i] || urls[0],
|
url: urls[i] || urls[0],
|
||||||
icon: icons[i] || 'docker',
|
icon: icons[i] || 'docker',
|
||||||
category: category.id,
|
categoryId: category.id,
|
||||||
orderId: orders[i] || 500,
|
orderId: orders[i] || 500,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,6 @@ const useDocker = async (apps) => {
|
||||||
await app.update({ isPinned: false });
|
await app.update({ isPinned: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const item of dockerApps) {
|
for (const item of dockerApps) {
|
||||||
// If app already exists, update it
|
// If app already exists, update it
|
||||||
if (apps.some((app) => app.name === item.name)) {
|
if (apps.some((app) => app.name === item.name)) {
|
||||||
|
|
|
@ -67,7 +67,7 @@ const useKubernetes = async (apps) => {
|
||||||
const icons = annotations['flame.pawelmalak/icon'] ? annotations['flame.pawelmalak/icon'].split(';') : [];
|
const icons = annotations['flame.pawelmalak/icon'] ? annotations['flame.pawelmalak/icon'].split(';') : [];
|
||||||
|
|
||||||
for (let i = 0; i < names.length; i++) {
|
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) {
|
if (!category) {
|
||||||
category = await createNewCategory(categoriesLabels[i]);
|
category = await createNewCategory(categoriesLabels[i]);
|
||||||
if (category) {
|
if (category) {
|
||||||
|
@ -81,7 +81,7 @@ const useKubernetes = async (apps) => {
|
||||||
name: names[i] || names[0],
|
name: names[i] || names[0],
|
||||||
url: urls[i] || urls[0],
|
url: urls[i] || urls[0],
|
||||||
icon: icons[i] || 'kubernetes',
|
icon: icons[i] || 'kubernetes',
|
||||||
category: category.id,
|
categoryId: category.id,
|
||||||
orderId: orders[i] || 500,
|
orderId: orders[i] || 500,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,11 @@ const { useKubernetes, useDocker } = require('./docker');
|
||||||
// @access Public
|
// @access Public
|
||||||
const getAllApps = asyncWrapper(async (req, res, next) => {
|
const getAllApps = asyncWrapper(async (req, res, next) => {
|
||||||
const {
|
const {
|
||||||
useOrdering: orderType,
|
useOrdering: orderType
|
||||||
dockerApps: useDockerAPI,
|
|
||||||
kubernetesApps: useKubernetesAPI,
|
|
||||||
} = await loadConfig();
|
} = await loadConfig();
|
||||||
|
|
||||||
let apps = await loadIntegrationsApps();
|
// Load apps to create/update apps from integrations (Docker, Kubernetes, etc.)
|
||||||
|
await initIntegrationsApps();
|
||||||
|
|
||||||
// apps visibility
|
// apps visibility
|
||||||
const where = req.isAuthenticated ? {} : { isPublic: true };
|
const where = req.isAuthenticated ? {} : { isPublic: true };
|
||||||
|
@ -44,26 +43,4 @@ const getAllApps = asyncWrapper(async (req, res, next) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const loadIntegrationsApps = asyncWrapper(async () => {
|
module.exports = getAllApps;
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
42
controllers/apps/getIntegrationsApps.js
Normal file
42
controllers/apps/getIntegrationsApps.js
Normal 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;
|
|
@ -4,5 +4,5 @@ module.exports = {
|
||||||
deleteApp: require('./deleteApp'),
|
deleteApp: require('./deleteApp'),
|
||||||
updateApp: require('./updateApp'),
|
updateApp: require('./updateApp'),
|
||||||
reorderApps: require('./reorderApps'),
|
reorderApps: require('./reorderApps'),
|
||||||
getAllApps: require('./getAllApps').getAllApps,
|
getAllApps: require('./getAllApps'),
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@ const App = require('../../models/App');
|
||||||
const Bookmark = require('../../models/Bookmark');
|
const Bookmark = require('../../models/Bookmark');
|
||||||
const { Sequelize } = require('sequelize');
|
const { Sequelize } = require('sequelize');
|
||||||
const loadConfig = require('../../utils/loadConfig');
|
const loadConfig = require('../../utils/loadConfig');
|
||||||
const loadIntegrationsApps = require('../apps/getAllApps').loadIntegrationsApps;
|
const initIntegrationsApps = require('../../utils/init/initIntegrationsApps');
|
||||||
|
|
||||||
// @desc Get all categories
|
// @desc Get all categories
|
||||||
// @route GET /api/categories
|
// @route GET /api/categories
|
||||||
|
@ -12,8 +12,8 @@ const loadIntegrationsApps = require('../apps/getAllApps').loadIntegrationsApps;
|
||||||
const getAllCategories = asyncWrapper(async (req, res, next) => {
|
const getAllCategories = asyncWrapper(async (req, res, next) => {
|
||||||
const { useOrdering: orderType } = await loadConfig();
|
const { useOrdering: orderType } = await loadConfig();
|
||||||
|
|
||||||
// Load apps to create apps from integrations (Docker, Kubernetes, etc.)
|
// Load apps to create/update apps from integrations (Docker, Kubernetes, etc.)
|
||||||
await loadIntegrationsApps();
|
await initIntegrationsApps();
|
||||||
|
|
||||||
let categories;
|
let categories;
|
||||||
let output;
|
let output;
|
||||||
|
|
|
@ -13,6 +13,7 @@ const Sockets = require('./Sockets');
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
const initApp = require('./utils/init');
|
const initApp = require('./utils/init');
|
||||||
|
const initIntegrationsApps = require('./utils/init/initIntegrationsApps');
|
||||||
const Logger = require('./utils/Logger');
|
const Logger = require('./utils/Logger');
|
||||||
const logger = new Logger();
|
const logger = new Logger();
|
||||||
|
|
||||||
|
@ -22,7 +23,10 @@ const logger = new Logger();
|
||||||
// Init app
|
// Init app
|
||||||
await initApp();
|
await initApp();
|
||||||
await connectDB();
|
await connectDB();
|
||||||
await associateModels();
|
await associateModels();
|
||||||
|
|
||||||
|
// Load apps to create/update apps from integrations (Docker, Kubernetes, etc.)
|
||||||
|
await initIntegrationsApps();
|
||||||
|
|
||||||
// Create server for Express API and WebSockets
|
// Create server for Express API and WebSockets
|
||||||
const server = http.createServer();
|
const server = http.createServer();
|
||||||
|
|
24
utils/init/initIntegrationsApps.js
Normal file
24
utils/init/initIntegrationsApps.js
Normal 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;
|
|
@ -14,6 +14,7 @@
|
||||||
"searchSameTab": false,
|
"searchSameTab": false,
|
||||||
"hideApps": false,
|
"hideApps": false,
|
||||||
"hideBookmarks": false,
|
"hideBookmarks": false,
|
||||||
|
"hideEmptyCategories": true,
|
||||||
"hideSearch": false,
|
"hideSearch": false,
|
||||||
"defaultSearchProvider": "l",
|
"defaultSearchProvider": "l",
|
||||||
"dockerApps": false,
|
"dockerApps": false,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue