Skip to content

Commit 3c0d720

Browse files
feat(ui) Add readOnly flag that disables profile URL editing (#8067)
1 parent 0612c70 commit 3c0d720

File tree

8 files changed

+58
-14
lines changed

8 files changed

+58
-14
lines changed

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,8 @@ private void configureQueryResolvers(final RuntimeWiring.Builder builder) {
694694
this.telemetryConfiguration,
695695
this.testsConfiguration,
696696
this.datahubConfiguration,
697-
this.viewsConfiguration
697+
this.viewsConfiguration,
698+
this.featureFlags
698699
))
699700
.dataFetcher("me", new MeResolver(this.entityClient, featureFlags))
700701
.dataFetcher("search", new SearchResolver(this.entityClient))

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/featureflags/FeatureFlags.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ public class FeatureFlags {
99
private boolean lineageSearchCacheEnabled = false;
1010
private boolean pointInTimeCreationEnabled = false;
1111
private boolean alwaysEmitChangeLog = false;
12+
private boolean readOnlyModeEnabled = false;
1213
}

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/config/AppConfigResolver.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
import com.datahub.authentication.AuthenticationConfiguration;
44
import com.datahub.authorization.AuthorizationConfiguration;
55
import com.linkedin.datahub.graphql.QueryContext;
6+
import com.linkedin.datahub.graphql.featureflags.FeatureFlags;
67
import com.linkedin.datahub.graphql.generated.AnalyticsConfig;
78
import com.linkedin.datahub.graphql.generated.AppConfig;
89
import com.linkedin.datahub.graphql.generated.AuthConfig;
910
import com.linkedin.datahub.graphql.generated.EntityType;
11+
import com.linkedin.datahub.graphql.generated.FeatureFlagsConfig;
1012
import com.linkedin.datahub.graphql.generated.IdentityManagementConfig;
1113
import com.linkedin.datahub.graphql.generated.LineageConfig;
1214
import com.linkedin.datahub.graphql.generated.ManagedIngestionConfig;
@@ -47,6 +49,7 @@ public class AppConfigResolver implements DataFetcher<CompletableFuture<AppConfi
4749
private final TestsConfiguration _testsConfiguration;
4850
private final DataHubConfiguration _datahubConfiguration;
4951
private final ViewsConfiguration _viewsConfiguration;
52+
private final FeatureFlags _featureFlags;
5053

5154
public AppConfigResolver(
5255
final GitVersion gitVersion,
@@ -59,7 +62,8 @@ public AppConfigResolver(
5962
final TelemetryConfiguration telemetryConfiguration,
6063
final TestsConfiguration testsConfiguration,
6164
final DataHubConfiguration datahubConfiguration,
62-
final ViewsConfiguration viewsConfiguration) {
65+
final ViewsConfiguration viewsConfiguration,
66+
final FeatureFlags featureFlags) {
6367
_gitVersion = gitVersion;
6468
_isAnalyticsEnabled = isAnalyticsEnabled;
6569
_ingestionConfiguration = ingestionConfiguration;
@@ -71,6 +75,7 @@ public AppConfigResolver(
7175
_testsConfiguration = testsConfiguration;
7276
_datahubConfiguration = datahubConfiguration;
7377
_viewsConfiguration = viewsConfiguration;
78+
_featureFlags = featureFlags;
7479
}
7580

7681
@Override
@@ -142,6 +147,10 @@ public CompletableFuture<AppConfig> get(final DataFetchingEnvironment environmen
142147
viewsConfig.setEnabled(_viewsConfiguration.isEnabled());
143148
appConfig.setViewsConfig(viewsConfig);
144149

150+
final FeatureFlagsConfig featureFlagsConfig = new FeatureFlagsConfig();
151+
featureFlagsConfig.setReadOnlyModeEnabled(_featureFlags.isReadOnlyModeEnabled());
152+
appConfig.setFeatureFlags(featureFlagsConfig);
153+
145154
return CompletableFuture.completedFuture(appConfig);
146155
}
147156

datahub-graphql-core/src/main/resources/app.graphql

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ type AppConfig {
181181
Configurations related to DataHub Views
182182
"""
183183
viewsConfig: ViewsConfig!
184+
185+
"""
186+
Feature flags telling the UI whether a feature is enabled or not
187+
"""
188+
featureFlags: FeatureFlagsConfig!
184189
}
185190

186191
"""
@@ -360,6 +365,17 @@ type ViewsConfig {
360365
enabled: Boolean!
361366
}
362367

368+
"""
369+
Configurations related to DataHub Views feature
370+
"""
371+
type FeatureFlagsConfig {
372+
"""
373+
Whether read only mode is enabled on an instance.
374+
Right now this only affects ability to edit user profile image URL but can be extended.
375+
"""
376+
readOnlyModeEnabled: Boolean!
377+
}
378+
363379
"""
364380
Input required to update Global View Settings.
365381
"""

datahub-web-react/src/app/entity/user/UserEditProfileModal.tsx

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import React, { useEffect, useState } from 'react';
2-
import { message, Button, Input, Modal, Typography, Form } from 'antd';
2+
import { message, Button, Input, Modal, Typography, Form, Tooltip } from 'antd';
33
import { useUpdateCorpUserPropertiesMutation } from '../../../graphql/user.generated';
44
import { useEnterKeyListener } from '../../shared/useEnterKeyListener';
5+
import { useAppConfig } from '../../useAppConfig';
56

67
type PropsData = {
78
name: string | undefined;
@@ -24,6 +25,8 @@ type Props = {
2425
export const USER_NAME_REGEX = new RegExp('^[a-zA-Z ]*$');
2526

2627
export default function UserEditProfileModal({ visible, onClose, onSave, editModalData }: Props) {
28+
const { config } = useAppConfig();
29+
const { readOnlyModeEnabled } = config.featureFlags;
2730
const [updateCorpUserPropertiesMutation] = useUpdateCorpUserPropertiesMutation();
2831
const [form] = Form.useForm();
2932

@@ -149,18 +152,25 @@ export default function UserEditProfileModal({ visible, onClose, onSave, editMod
149152
onChange={(event) => setData({ ...data, title: event.target.value })}
150153
/>
151154
</Form.Item>
152-
<Form.Item
153-
name="image"
154-
label={<Typography.Text strong>Image URL</Typography.Text>}
155-
rules={[{ whitespace: true }, { type: 'url', message: 'not valid url' }]}
156-
hasFeedback
155+
<Tooltip
156+
title="Editing image URL has been disabled."
157+
overlayStyle={readOnlyModeEnabled ? {} : { display: 'none' }}
158+
placement="bottom"
157159
>
158-
<Input
159-
placeholder="https://www.example.com/photo.png"
160-
value={data.image}
161-
onChange={(event) => setData({ ...data, image: event.target.value })}
162-
/>
163-
</Form.Item>
160+
<Form.Item
161+
name="image"
162+
label={<Typography.Text strong>Image URL</Typography.Text>}
163+
rules={[{ whitespace: true }, { type: 'url', message: 'not valid url' }]}
164+
hasFeedback
165+
>
166+
<Input
167+
placeholder="https://www.example.com/photo.png"
168+
value={data.image}
169+
onChange={(event) => setData({ ...data, image: event.target.value })}
170+
disabled={readOnlyModeEnabled}
171+
/>
172+
</Form.Item>
173+
</Tooltip>
164174
<Form.Item
165175
name="team"
166176
label={<Typography.Text strong>Team</Typography.Text>}

datahub-web-react/src/appConfigContext.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ export const DEFAULT_APP_CONFIG = {
3737
viewsConfig: {
3838
enabled: false,
3939
},
40+
featureFlags: {
41+
readOnlyModeEnabled: false,
42+
},
4043
};
4144

4245
export const AppConfigContext = React.createContext<{

datahub-web-react/src/graphql/app.graphql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ query appConfig {
5050
viewsConfig {
5151
enabled
5252
}
53+
featureFlags {
54+
readOnlyModeEnabled
55+
}
5356
}
5457
}
5558

metadata-service/factories/src/main/resources/application.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ featureFlags:
279279
pointInTimeCreationEnabled: ${POINT_IN_TIME_CREATION_ENABLED:false} # Enables creation of point in time snapshots for the scroll API, only works with main line ElasticSearch releases after 7.10. OpenSearch is unsupported, plans to eventually target OpenSearch 2.4+ with a divergent client
280280
alwaysEmitChangeLog: ${ALWAYS_EMIT_CHANGE_LOG:false} # Enables always emitting a MCL even when no changes are detected. Used for Time Based Lineage when no changes occur.
281281
searchServiceDiffModeEnabled: ${SEARCH_SERVICE_DIFF_MODE_ENABLED:true} # Enables diff mode for search document writes, reduces amount of writes to ElasticSearch documents for no-ops
282+
readOnlyModeEnabled: ${READ_ONLY_MODE_ENABLED:false} # Enables read only mode for an instance. Right now this only affects ability to edit user profile image URL but can be extended
282283

283284
entityChangeEvents:
284285
enabled: ${ENABLE_ENTITY_CHANGE_EVENTS_HOOK:true}

0 commit comments

Comments
 (0)