diff --git a/.env.defaults b/.env.defaults new file mode 100644 index 000000000..18cd58c1e --- /dev/null +++ b/.env.defaults @@ -0,0 +1 @@ +PORTAINER_EDITION=CE \ No newline at end of file diff --git a/app/docker/containers/components/ContainersDatatable/ContainersDatatable.tsx b/app/docker/containers/components/ContainersDatatable/ContainersDatatable.tsx index 742c65860..0e8ef9cdf 100644 --- a/app/docker/containers/components/ContainersDatatable/ContainersDatatable.tsx +++ b/app/docker/containers/components/ContainersDatatable/ContainersDatatable.tsx @@ -191,19 +191,27 @@ export function ContainersDatatable({ role={tbodyProps.role} style={tbodyProps.style} > - {page.map((row) => { - prepareRow(row); - const { key, className, role, style } = row.getRowProps(); - return ( - - cells={row.cells} - key={key} - className={className} - role={role} - style={style} - /> - ); - })} + {page.length > 0 ? ( + page.map((row) => { + prepareRow(row); + const { key, className, role, style } = row.getRowProps(); + return ( + + cells={row.cells} + key={key} + className={className} + role={role} + style={style} + /> + ); + }) + ) : ( + + + No container available. + + + )} diff --git a/app/index.js b/app/index.js index 5fc05f75e..fc95940c3 100644 --- a/app/index.js +++ b/app/index.js @@ -20,7 +20,7 @@ import { configApp } from './config'; import { init as initFeatureService } from './portainer/feature-flags/feature-flags.service'; import { Edition } from './portainer/feature-flags/enums'; -initFeatureService(Edition.CE); +initFeatureService(Edition[process.env.PORTAINER_EDITION]); angular .module('portainer', [ diff --git a/app/portainer/feature-flags/feature-flags.service.ts b/app/portainer/feature-flags/feature-flags.service.ts index 623da5fb0..e072d561b 100644 --- a/app/portainer/feature-flags/feature-flags.service.ts +++ b/app/portainer/feature-flags/feature-flags.service.ts @@ -10,7 +10,7 @@ const state: ServiceState = { features: >{}, }; -export async function init(edition: Edition = Edition.CE) { +export async function init(edition: Edition) { // will be loaded on runtime const currentEdition = edition; const features = { diff --git a/app/portainer/hooks/useUser.tsx b/app/portainer/hooks/useUser.tsx index bd1e070c4..1c605aba8 100644 --- a/app/portainer/hooks/useUser.tsx +++ b/app/portainer/hooks/useUser.tsx @@ -33,13 +33,20 @@ export function useUser() { return context; } -export function useAuthorizations(authorizations: string | string[]) { +export function useAuthorizations( + authorizations: string | string[], + adminOnlyCE = false +) { const authorizationsArray = typeof authorizations === 'string' ? [authorizations] : authorizations; const { user } = useUser(); const { params } = useCurrentStateAndParams(); + if (process.env.PORTAINER_EDITION === 'CE') { + return !adminOnlyCE || isAdmin(user); + } + const { endpointId } = params; if (!endpointId) { return false; @@ -118,6 +125,6 @@ export function UserProvider({ children }: UserProviderProps) { } } -function isAdmin(user: UserViewModel): boolean { - return user.Role === 1; +function isAdmin(user?: UserViewModel | null) { + return !!user && user.Role === 1; } diff --git a/webpack/webpack.common.js b/webpack/webpack.common.js index 63a18323b..c86d53374 100644 --- a/webpack/webpack.common.js +++ b/webpack/webpack.common.js @@ -98,7 +98,7 @@ module.exports = { }, }, plugins: [ - new Dotenv(), + new Dotenv({ defaults: true }), new ESLintPlugin(), new HtmlWebpackPlugin({ template: './app/index.html',