mirror of
https://github.com/datahub-project/datahub.git
synced 2025-10-27 08:54:32 +00:00
set custom logo without rebuilding (#4674)
This commit is contained in:
parent
8e2bd00059
commit
0c61dee07b
@ -52,6 +52,7 @@ import com.linkedin.datahub.graphql.generated.SearchAcrossLineageResult;
|
||||
import com.linkedin.datahub.graphql.generated.SearchResult;
|
||||
import com.linkedin.datahub.graphql.generated.UsageQueryResult;
|
||||
import com.linkedin.datahub.graphql.generated.UserUsageCounts;
|
||||
import com.linkedin.datahub.graphql.generated.VisualConfiguration;
|
||||
import com.linkedin.datahub.graphql.resolvers.AuthenticatedResolver;
|
||||
import com.linkedin.datahub.graphql.resolvers.MeResolver;
|
||||
import com.linkedin.datahub.graphql.resolvers.assertion.AssertionRunEventResolver;
|
||||
@ -221,6 +222,7 @@ public class GmsGraphQLEngine {
|
||||
|
||||
private final IngestionConfiguration ingestionConfiguration;
|
||||
private final AuthorizationConfiguration authorizationConfiguration;
|
||||
private final VisualConfiguration visualConfiguration;
|
||||
|
||||
private final DatasetType datasetType;
|
||||
private final CorpUserType corpUserType;
|
||||
@ -286,7 +288,8 @@ public class GmsGraphQLEngine {
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false);
|
||||
false,
|
||||
null);
|
||||
}
|
||||
|
||||
public GmsGraphQLEngine(
|
||||
@ -303,7 +306,8 @@ public class GmsGraphQLEngine {
|
||||
final IngestionConfiguration ingestionConfiguration,
|
||||
final AuthorizationConfiguration authorizationConfiguration,
|
||||
final GitVersion gitVersion,
|
||||
final boolean supportsImpactAnalysis
|
||||
final boolean supportsImpactAnalysis,
|
||||
final VisualConfiguration visualConfiguration
|
||||
) {
|
||||
|
||||
this.entityClient = entityClient;
|
||||
@ -322,6 +326,7 @@ public class GmsGraphQLEngine {
|
||||
|
||||
this.ingestionConfiguration = Objects.requireNonNull(ingestionConfiguration);
|
||||
this.authorizationConfiguration = Objects.requireNonNull(authorizationConfiguration);
|
||||
this.visualConfiguration = visualConfiguration;
|
||||
|
||||
this.datasetType = new DatasetType(entityClient);
|
||||
this.corpUserType = new CorpUserType(entityClient);
|
||||
@ -558,7 +563,7 @@ public class GmsGraphQLEngine {
|
||||
new AppConfigResolver(gitVersion, analyticsService != null,
|
||||
this.ingestionConfiguration,
|
||||
this.authorizationConfiguration,
|
||||
supportsImpactAnalysis))
|
||||
supportsImpactAnalysis, this.visualConfiguration))
|
||||
.dataFetcher("me", new AuthenticatedResolver<>(
|
||||
new MeResolver(this.entityClient)))
|
||||
.dataFetcher("search", new AuthenticatedResolver<>(
|
||||
|
||||
@ -11,6 +11,7 @@ import com.linkedin.datahub.graphql.generated.ManagedIngestionConfig;
|
||||
import com.linkedin.datahub.graphql.generated.PoliciesConfig;
|
||||
import com.linkedin.datahub.graphql.generated.Privilege;
|
||||
import com.linkedin.datahub.graphql.generated.ResourcePrivileges;
|
||||
import com.linkedin.datahub.graphql.generated.VisualConfiguration;
|
||||
import com.linkedin.metadata.config.IngestionConfiguration;
|
||||
import com.linkedin.metadata.version.GitVersion;
|
||||
import graphql.schema.DataFetcher;
|
||||
@ -29,18 +30,21 @@ public class AppConfigResolver implements DataFetcher<CompletableFuture<AppConfi
|
||||
private final IngestionConfiguration _ingestionConfiguration;
|
||||
private final AuthorizationConfiguration _authorizationConfiguration;
|
||||
private final boolean _supportsImpactAnalysis;
|
||||
private final VisualConfiguration _visualConfiguration;
|
||||
|
||||
public AppConfigResolver(
|
||||
final GitVersion gitVersion,
|
||||
final boolean isAnalyticsEnabled,
|
||||
final IngestionConfiguration ingestionConfiguration,
|
||||
final AuthorizationConfiguration authorizationConfiguration,
|
||||
final boolean supportsImpactAnalysis) {
|
||||
final boolean supportsImpactAnalysis,
|
||||
final VisualConfiguration visualConfiguration) {
|
||||
_gitVersion = gitVersion;
|
||||
_isAnalyticsEnabled = isAnalyticsEnabled;
|
||||
_ingestionConfiguration = ingestionConfiguration;
|
||||
_authorizationConfiguration = authorizationConfiguration;
|
||||
_supportsImpactAnalysis = supportsImpactAnalysis;
|
||||
_visualConfiguration = visualConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -83,6 +87,8 @@ public class AppConfigResolver implements DataFetcher<CompletableFuture<AppConfi
|
||||
appConfig.setIdentityManagementConfig(identityManagementConfig);
|
||||
appConfig.setManagedIngestionConfig(ingestionConfig);
|
||||
|
||||
appConfig.setVisualConfig(_visualConfiguration);
|
||||
|
||||
return CompletableFuture.completedFuture(appConfig);
|
||||
}
|
||||
|
||||
|
||||
@ -102,6 +102,21 @@ type AppConfig {
|
||||
Configurations related to Lineage
|
||||
"""
|
||||
lineageConfig: LineageConfig!
|
||||
|
||||
"""
|
||||
Configurations related to visual appearance, allows styling the UI without rebuilding the bundle
|
||||
"""
|
||||
visualConfig: VisualConfiguration!
|
||||
}
|
||||
|
||||
"""
|
||||
Configurations related to visual appearance of the app
|
||||
"""
|
||||
type VisualConfiguration {
|
||||
"""
|
||||
Custom logo url for the homepage & top banner
|
||||
"""
|
||||
logoUrl: String
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
@ -72,6 +72,11 @@ The best workaround is to revert to the Active LTS version of Node, 16.13.0 with
|
||||
|
||||
### Theming
|
||||
|
||||
#### Customizing your App without rebuilding assets
|
||||
|
||||
To see the results of any change to a theme, you will need to rebuild your datahub-frontend-react container. While this may work for some users, if you don't want to rebuild your container
|
||||
you can still customize the homepage's logo without rebuilding. You can do this by setting the REACT_APP_LOGO_URL env variable when deploying GMS.
|
||||
|
||||
#### Selecting a theme
|
||||
|
||||
Theme configurations are stored in `./src/conf/theme`. To select a theme, choose one and update the `REACT_APP_THEME_CONFIG` env variable stored in `.env`.
|
||||
|
||||
@ -16,6 +16,7 @@ import { EntityType } from '../../types.generated';
|
||||
import analytics, { EventType } from '../analytics';
|
||||
import { AdminHeaderLinks } from '../shared/admin/AdminHeaderLinks';
|
||||
import { ANTD_GRAY } from '../entity/shared/constants';
|
||||
import { useAppConfig } from '../useAppConfig';
|
||||
|
||||
const Background = styled.div`
|
||||
width: 100%;
|
||||
@ -115,6 +116,7 @@ export const HomePageHeader = () => {
|
||||
const [getAutoCompleteResultsForMultiple, { data: suggestionsData }] = useGetAutoCompleteMultipleResultsLazyQuery();
|
||||
const user = useGetAuthenticatedUser()?.corpUser;
|
||||
const themeConfig = useTheme();
|
||||
const appConfig = useAppConfig();
|
||||
|
||||
const onSearch = (query: string, type?: EntityType) => {
|
||||
if (!query || query.trim().length === 0) {
|
||||
@ -193,7 +195,11 @@ export const HomePageHeader = () => {
|
||||
</NavGroup>
|
||||
</Row>
|
||||
<HeaderContainer>
|
||||
<Image src={themeConfig.assets.logoUrl} preview={false} style={styles.logoImage} />
|
||||
<Image
|
||||
src={appConfig.config.visualConfig.logoUrl || themeConfig.assets.logoUrl}
|
||||
preview={false}
|
||||
style={styles.logoImage}
|
||||
/>
|
||||
{!!themeConfig.content.subtitle && (
|
||||
<Typography.Text style={styles.subtitle}>{themeConfig.content.subtitle}</Typography.Text>
|
||||
)}
|
||||
|
||||
@ -9,6 +9,7 @@ import { AutoCompleteResultForEntity, EntityType } from '../../types.generated';
|
||||
import EntityRegistry from '../entity/EntityRegistry';
|
||||
import { ANTD_GRAY } from '../entity/shared/constants';
|
||||
import { AdminHeaderLinks } from '../shared/admin/AdminHeaderLinks';
|
||||
import { useAppConfig } from '../useAppConfig';
|
||||
|
||||
const { Header } = Layout;
|
||||
|
||||
@ -74,12 +75,16 @@ export const SearchHeader = ({
|
||||
entityRegistry,
|
||||
}: Props) => {
|
||||
const themeConfig = useTheme();
|
||||
const appConfig = useAppConfig();
|
||||
|
||||
return (
|
||||
<Header style={styles.header as any}>
|
||||
<LogoSearchContainer>
|
||||
<Link to="/">
|
||||
<LogoImage src={themeConfig.assets.logoUrl} preview={false} />
|
||||
<LogoImage
|
||||
src={appConfig.config.visualConfig.logoUrl || themeConfig.assets.logoUrl}
|
||||
preview={false}
|
||||
/>
|
||||
</Link>
|
||||
<SearchBar
|
||||
initialQuery={initialQuery}
|
||||
|
||||
@ -19,6 +19,9 @@ export const DEFAULT_APP_CONFIG = {
|
||||
lineageConfig: {
|
||||
supportsImpactAnalysis: false,
|
||||
},
|
||||
visualConfig: {
|
||||
logoUrl: undefined,
|
||||
},
|
||||
};
|
||||
|
||||
export const AppConfigContext = React.createContext<{
|
||||
|
||||
@ -31,6 +31,9 @@ query appConfig {
|
||||
managedIngestionConfig {
|
||||
enabled
|
||||
}
|
||||
visualConfig {
|
||||
logoUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
package com.linkedin.gms.factory.common;
|
||||
|
||||
import com.linkedin.datahub.graphql.generated.VisualConfiguration;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
|
||||
@Configuration
|
||||
public class VisualConfigFactory {
|
||||
@Value("${visualConfig.assets.logoUrl}")
|
||||
private String logoUrl;
|
||||
|
||||
@Nonnull
|
||||
@Bean(name = "visualConfig")
|
||||
protected VisualConfiguration getInstance() {
|
||||
VisualConfiguration config = new VisualConfiguration();
|
||||
config.setLogoUrl(logoUrl);
|
||||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ import com.datahub.authentication.token.TokenService;
|
||||
import com.linkedin.datahub.graphql.GmsGraphQLEngine;
|
||||
import com.linkedin.datahub.graphql.GraphQLEngine;
|
||||
import com.linkedin.datahub.graphql.analytics.service.AnalyticsService;
|
||||
import com.linkedin.datahub.graphql.generated.VisualConfiguration;
|
||||
import com.linkedin.entity.client.JavaEntityClient;
|
||||
import com.linkedin.gms.factory.auth.DataHubTokenServiceFactory;
|
||||
import com.linkedin.gms.factory.common.GitVersionFactory;
|
||||
@ -92,6 +93,10 @@ public class GraphQLEngineFactory {
|
||||
@Qualifier("gitVersion")
|
||||
private GitVersion _gitVersion;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("visualConfig")
|
||||
private VisualConfiguration _visualConfiguration;
|
||||
|
||||
@Value("${platformAnalytics.enabled}") // TODO: Migrate to DATAHUB_ANALYTICS_ENABLED
|
||||
private Boolean isAnalyticsEnabled;
|
||||
|
||||
@ -113,7 +118,8 @@ public class GraphQLEngineFactory {
|
||||
_configProvider.getIngestion(),
|
||||
_configProvider.getAuthorization(),
|
||||
_gitVersion,
|
||||
_graphService.supportsMultiHop()
|
||||
_graphService.supportsMultiHop(),
|
||||
_visualConfiguration
|
||||
).builder().build();
|
||||
}
|
||||
return new GmsGraphQLEngine(
|
||||
@ -130,7 +136,8 @@ public class GraphQLEngineFactory {
|
||||
_configProvider.getIngestion(),
|
||||
_configProvider.getAuthorization(),
|
||||
_gitVersion,
|
||||
_graphService.supportsMultiHop()
|
||||
_graphService.supportsMultiHop(),
|
||||
_visualConfiguration
|
||||
).builder().build();
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,6 +81,10 @@ configEntityRegistry:
|
||||
platformAnalytics:
|
||||
enabled: ${ANALYTICS_ENABLED:true}
|
||||
|
||||
visualConfig:
|
||||
assets:
|
||||
logoUrl: ${REACT_APP_LOGO_URL:#{null}}
|
||||
|
||||
# Storage Layer
|
||||
ebean:
|
||||
username: ${EBEAN_DATASOURCE_USERNAME:datahub}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user