feat: Feat/add google sheets metdata (#22577)
This PR does three things: 1. Cleans up the Datasource Form page and makes the code more readable and discoverable 2. Adds the Account information for google sheets 3. Adds a way to render form configs specifically in view or edit modes.
This commit is contained in:
parent
82d931e173
commit
f87ba6a671
|
|
@ -1571,8 +1571,7 @@ export const RECONNECT_BUTTON_TEXT = () => "RECONNECT";
|
||||||
export const SAVE_BUTTON_TEXT = () => "SAVE";
|
export const SAVE_BUTTON_TEXT = () => "SAVE";
|
||||||
export const SAVE_AND_AUTHORIZE_BUTTON_TEXT = () => "SAVE AND AUTHORIZE";
|
export const SAVE_AND_AUTHORIZE_BUTTON_TEXT = () => "SAVE AND AUTHORIZE";
|
||||||
export const DISCARD_POPUP_DONT_SAVE_BUTTON_TEXT = () => "DON'T SAVE";
|
export const DISCARD_POPUP_DONT_SAVE_BUTTON_TEXT = () => "DON'T SAVE";
|
||||||
export const GSHEET_AUTHORISED_FILE_IDS_KEY = () =>
|
export const GSHEET_AUTHORISED_FILE_IDS_KEY = () => "userAuthorizedSheetIds";
|
||||||
"Google sheets authorised file ids key";
|
|
||||||
export const GOOGLE_SHEETS_INFO_BANNER_MESSAGE = () =>
|
export const GOOGLE_SHEETS_INFO_BANNER_MESSAGE = () =>
|
||||||
"Appsmith will require access to your google drive to access google sheets.";
|
"Appsmith will require access to your google drive to access google sheets.";
|
||||||
export const GOOGLE_SHEETS_AUTHORIZE_DATASOURCE = () => "Authorize Datasource";
|
export const GOOGLE_SHEETS_AUTHORIZE_DATASOURCE = () => "Authorize Datasource";
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,12 @@ export type ComparisonOperations =
|
||||||
| "GREATER"
|
| "GREATER"
|
||||||
| "IN"
|
| "IN"
|
||||||
| "NOT_IN"
|
| "NOT_IN"
|
||||||
| "FEATURE_FLAG";
|
| "FEATURE_FLAG"
|
||||||
|
| "VIEW_MODE";
|
||||||
|
|
||||||
|
export enum ComparisonOperationsEnum {
|
||||||
|
VIEW_MODE = "VIEW_MODE",
|
||||||
|
}
|
||||||
|
|
||||||
export type HiddenType = boolean | Condition | ConditionObject;
|
export type HiddenType = boolean | Condition | ConditionObject;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ export const caculateIsHidden = (
|
||||||
values: any,
|
values: any,
|
||||||
hiddenConfig?: HiddenType,
|
hiddenConfig?: HiddenType,
|
||||||
featureFlags?: FeatureFlags,
|
featureFlags?: FeatureFlags,
|
||||||
|
viewMode?: boolean,
|
||||||
) => {
|
) => {
|
||||||
if (!!hiddenConfig && !isBoolean(hiddenConfig)) {
|
if (!!hiddenConfig && !isBoolean(hiddenConfig)) {
|
||||||
let valueAtPath;
|
let valueAtPath;
|
||||||
|
|
@ -102,6 +103,9 @@ export const caculateIsHidden = (
|
||||||
// and show new configs if feature flag is enabled, if disabled/ not present,
|
// and show new configs if feature flag is enabled, if disabled/ not present,
|
||||||
// previous config would be shown as is
|
// previous config would be shown as is
|
||||||
return !!featureFlags && featureFlags[flagValue] === value;
|
return !!featureFlags && featureFlags[flagValue] === value;
|
||||||
|
case "VIEW_MODE":
|
||||||
|
// This can be used to decide which form controls to show in view mode or edit mode depending on the value.
|
||||||
|
return viewMode === value;
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -112,13 +116,14 @@ export const isHidden = (
|
||||||
values: any,
|
values: any,
|
||||||
hiddenConfig?: HiddenType,
|
hiddenConfig?: HiddenType,
|
||||||
featureFlags?: FeatureFlags,
|
featureFlags?: FeatureFlags,
|
||||||
|
viewMode?: boolean,
|
||||||
) => {
|
) => {
|
||||||
if (!!hiddenConfig && !isBoolean(hiddenConfig)) {
|
if (!!hiddenConfig && !isBoolean(hiddenConfig)) {
|
||||||
if ("conditionType" in hiddenConfig) {
|
if ("conditionType" in hiddenConfig) {
|
||||||
//check if nested conditions exist
|
//check if nested conditions exist
|
||||||
return isHiddenConditionsEvaluation(values, hiddenConfig);
|
return isHiddenConditionsEvaluation(values, hiddenConfig);
|
||||||
} else {
|
} else {
|
||||||
return caculateIsHidden(values, hiddenConfig, featureFlags);
|
return caculateIsHidden(values, hiddenConfig, featureFlags, viewMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return !!hiddenConfig;
|
return !!hiddenConfig;
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,10 @@ import React from "react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import { useParams } from "react-router";
|
import { useParams } from "react-router";
|
||||||
import type { AppState } from "@appsmith/reducers";
|
import type { AppState } from "@appsmith/reducers";
|
||||||
import { isNil } from "lodash";
|
|
||||||
import { getDatasource, getPlugin } from "selectors/entitiesSelector";
|
import { getDatasource, getPlugin } from "selectors/entitiesSelector";
|
||||||
import { Colors } from "constants/Colors";
|
import { Colors } from "constants/Colors";
|
||||||
import { HeaderIcons } from "icons/HeaderIcons";
|
import { HeaderIcons } from "icons/HeaderIcons";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import RenderDatasourceInformation from "./DatasourceSection";
|
|
||||||
import NewActionButton from "./NewActionButton";
|
import NewActionButton from "./NewActionButton";
|
||||||
|
|
||||||
import { hasCreateDatasourceActionPermission } from "@appsmith/utils/permissionHelpers";
|
import { hasCreateDatasourceActionPermission } from "@appsmith/utils/permissionHelpers";
|
||||||
|
|
@ -28,16 +26,8 @@ const Header = styled.div`
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
border-bottom: 1px solid #d0d7dd;
|
|
||||||
padding: 24px 20px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
function Connected({
|
function Connected({
|
||||||
errorComponent,
|
errorComponent,
|
||||||
hideDatasourceRenderSection = false,
|
|
||||||
showDatasourceSavedText = true,
|
showDatasourceSavedText = true,
|
||||||
}: {
|
}: {
|
||||||
errorComponent?: JSX.Element | null;
|
errorComponent?: JSX.Element | null;
|
||||||
|
|
@ -50,10 +40,6 @@ function Connected({
|
||||||
getDatasource(state, params.datasourceId),
|
getDatasource(state, params.datasourceId),
|
||||||
);
|
);
|
||||||
|
|
||||||
const datasourceFormConfigs = useSelector(
|
|
||||||
(state: AppState) => state.entities.plugins.formConfigs,
|
|
||||||
);
|
|
||||||
|
|
||||||
const plugin = useSelector((state: AppState) =>
|
const plugin = useSelector((state: AppState) =>
|
||||||
getPlugin(state, datasource?.pluginId ?? ""),
|
getPlugin(state, datasource?.pluginId ?? ""),
|
||||||
);
|
);
|
||||||
|
|
@ -67,11 +53,8 @@ function Connected({
|
||||||
...pagePermissions,
|
...pagePermissions,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const currentFormConfig: Array<any> =
|
|
||||||
datasourceFormConfigs[datasource?.pluginId ?? ""];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper>
|
<>
|
||||||
{showDatasourceSavedText && (
|
{showDatasourceSavedText && (
|
||||||
<Header>
|
<Header>
|
||||||
<ConnectedText>
|
<ConnectedText>
|
||||||
|
|
@ -91,17 +74,7 @@ function Connected({
|
||||||
</Header>
|
</Header>
|
||||||
)}
|
)}
|
||||||
{errorComponent}
|
{errorComponent}
|
||||||
<div style={{ marginTop: showDatasourceSavedText ? "30px" : "" }}>
|
</>
|
||||||
{!isNil(currentFormConfig) &&
|
|
||||||
!isNil(datasource) &&
|
|
||||||
!hideDatasourceRenderSection ? (
|
|
||||||
<RenderDatasourceInformation
|
|
||||||
config={currentFormConfig[0]}
|
|
||||||
datasource={datasource}
|
|
||||||
/>
|
|
||||||
) : undefined}
|
|
||||||
</div>
|
|
||||||
</Wrapper>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import Debugger, {
|
||||||
} from "./Debugger";
|
} from "./Debugger";
|
||||||
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
|
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
|
||||||
import { showDebuggerFlag } from "selectors/debuggerSelectors";
|
import { showDebuggerFlag } from "selectors/debuggerSelectors";
|
||||||
|
import DatasourceInformation from "./DatasourceSection";
|
||||||
import { DocsLink, openDoc } from "../../../constants/DocumentationLinks";
|
import { DocsLink, openDoc } from "../../../constants/DocumentationLinks";
|
||||||
|
|
||||||
const { cloudHosting } = getAppsmithConfigs();
|
const { cloudHosting } = getAppsmithConfigs();
|
||||||
|
|
@ -86,6 +87,13 @@ export const Form = styled.form`
|
||||||
flex: 1;
|
flex: 1;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const ViewModeWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border-bottom: 1px solid #d0d7dd;
|
||||||
|
padding: 24px 20px;
|
||||||
|
`;
|
||||||
|
|
||||||
class DatasourceDBEditor extends JSONtoForm<Props> {
|
class DatasourceDBEditor extends JSONtoForm<Props> {
|
||||||
componentDidUpdate(prevProps: Props) {
|
componentDidUpdate(prevProps: Props) {
|
||||||
if (prevProps.datasourceId !== this.props.datasourceId) {
|
if (prevProps.datasourceId !== this.props.datasourceId) {
|
||||||
|
|
@ -125,6 +133,7 @@ class DatasourceDBEditor extends JSONtoForm<Props> {
|
||||||
datasourceButtonConfiguration,
|
datasourceButtonConfiguration,
|
||||||
datasourceDeleteTrigger,
|
datasourceDeleteTrigger,
|
||||||
datasourceId,
|
datasourceId,
|
||||||
|
formConfig,
|
||||||
formData,
|
formData,
|
||||||
messages,
|
messages,
|
||||||
pluginType,
|
pluginType,
|
||||||
|
|
@ -200,7 +209,20 @@ class DatasourceDBEditor extends JSONtoForm<Props> {
|
||||||
{""}
|
{""}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{viewMode && <Connected />}
|
{viewMode && (
|
||||||
|
<ViewModeWrapper>
|
||||||
|
<Connected />
|
||||||
|
<div style={{ marginTop: "30px" }}>
|
||||||
|
{!_.isNil(formConfig) && !_.isNil(datasource) ? (
|
||||||
|
<DatasourceInformation
|
||||||
|
config={formConfig[0]}
|
||||||
|
datasource={datasource}
|
||||||
|
viewMode={viewMode}
|
||||||
|
/>
|
||||||
|
) : undefined}
|
||||||
|
</div>
|
||||||
|
</ViewModeWrapper>
|
||||||
|
)}
|
||||||
{/* Render datasource form call-to-actions */}
|
{/* Render datasource form call-to-actions */}
|
||||||
{datasource && (
|
{datasource && (
|
||||||
<DatasourceAuth
|
<DatasourceAuth
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { Colors } from "constants/Colors";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { isHidden, isKVArray } from "components/formControls/utils";
|
import { isHidden, isKVArray } from "components/formControls/utils";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
import { ComparisonOperationsEnum } from "components/formControls/BaseControl";
|
||||||
|
|
||||||
const Key = styled.div`
|
const Key = styled.div`
|
||||||
color: ${Colors.DOVE_GRAY};
|
color: ${Colors.DOVE_GRAY};
|
||||||
|
|
@ -35,6 +36,7 @@ const FieldWrapper = styled.div`
|
||||||
export default class RenderDatasourceInformation extends React.Component<{
|
export default class RenderDatasourceInformation extends React.Component<{
|
||||||
config: any;
|
config: any;
|
||||||
datasource: Datasource;
|
datasource: Datasource;
|
||||||
|
viewMode?: boolean;
|
||||||
}> {
|
}> {
|
||||||
renderKVArray = (children: Array<any>) => {
|
renderKVArray = (children: Array<any>) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -85,11 +87,12 @@ export default class RenderDatasourceInformation extends React.Component<{
|
||||||
};
|
};
|
||||||
|
|
||||||
renderDatasourceSection(section: any) {
|
renderDatasourceSection(section: any) {
|
||||||
const { datasource } = this.props;
|
const { datasource, viewMode } = this.props;
|
||||||
return (
|
return (
|
||||||
<React.Fragment key={datasource.id}>
|
<React.Fragment key={datasource.id}>
|
||||||
{map(section.children, (section) => {
|
{map(section.children, (section) => {
|
||||||
if (isHidden(datasource, section.hidden)) return null;
|
if (isHidden(datasource, section.hidden, undefined, viewMode))
|
||||||
|
return null;
|
||||||
if ("children" in section) {
|
if ("children" in section) {
|
||||||
if (isKVArray(section.children)) {
|
if (isKVArray(section.children)) {
|
||||||
return this.renderKVArray(section.children);
|
return this.renderKVArray(section.children);
|
||||||
|
|
@ -123,6 +126,15 @@ export default class RenderDatasourceInformation extends React.Component<{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!value &&
|
||||||
|
!!viewMode &&
|
||||||
|
"comparison" in section.hidden &&
|
||||||
|
section.hidden.comparison === ComparisonOperationsEnum.VIEW_MODE
|
||||||
|
) {
|
||||||
|
value = section.initialValue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!value || (isArray(value) && value.length < 1)) {
|
if (!value || (isArray(value) && value.length < 1)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -246,7 +246,14 @@ export class JSONtoForm<
|
||||||
// hides features/configs that are hidden behind feature flag
|
// hides features/configs that are hidden behind feature flag
|
||||||
// TODO: remove hidden config property as well as this param,
|
// TODO: remove hidden config property as well as this param,
|
||||||
// when feature flag is removed
|
// when feature flag is removed
|
||||||
if (isHidden(this.props.formData, section.hidden, this.props?.featureFlags))
|
if (
|
||||||
|
isHidden(
|
||||||
|
this.props.formData,
|
||||||
|
section.hidden,
|
||||||
|
this.props?.featureFlags,
|
||||||
|
false, // viewMode is false here.
|
||||||
|
)
|
||||||
|
)
|
||||||
return null;
|
return null;
|
||||||
return (
|
return (
|
||||||
<Collapsible
|
<Collapsible
|
||||||
|
|
@ -314,8 +321,9 @@ export class JSONtoForm<
|
||||||
if (
|
if (
|
||||||
isHidden(
|
isHidden(
|
||||||
this.props.formData,
|
this.props.formData,
|
||||||
section.hidden,
|
propertyControlOrSection.hidden,
|
||||||
this.props?.featureFlags,
|
this.props?.featureFlags,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -738,7 +738,8 @@ export function EditorJSONtoForm(props: Props) {
|
||||||
(section: any): any => {
|
(section: any): any => {
|
||||||
return section.children.map(
|
return section.children.map(
|
||||||
(formControlOrSection: ControlProps, idx: number) => {
|
(formControlOrSection: ControlProps, idx: number) => {
|
||||||
if (isHidden(props.formData, section.hidden)) return null;
|
if (isHidden(props.formData, section.hidden, undefined, false))
|
||||||
|
return null;
|
||||||
if (formControlOrSection.hasOwnProperty("children")) {
|
if (formControlOrSection.hasOwnProperty("children")) {
|
||||||
return renderEachConfig(formName)(formControlOrSection);
|
return renderEachConfig(formName)(formControlOrSection);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ import {
|
||||||
} from "../DataSourceEditor/JSONtoForm";
|
} from "../DataSourceEditor/JSONtoForm";
|
||||||
import { getConfigInitialValues } from "components/formControls/utils";
|
import { getConfigInitialValues } from "components/formControls/utils";
|
||||||
import Connected from "../DataSourceEditor/Connected";
|
import Connected from "../DataSourceEditor/Connected";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getCurrentApplicationId,
|
getCurrentApplicationId,
|
||||||
getGsheetProjectID,
|
getGsheetProjectID,
|
||||||
|
|
@ -71,6 +70,8 @@ import { getDatasourceErrorMessage } from "./errorUtils";
|
||||||
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
|
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
|
||||||
import { DocumentationLink } from "../QueryEditor/EditorJSONtoForm";
|
import { DocumentationLink } from "../QueryEditor/EditorJSONtoForm";
|
||||||
import GoogleSheetFilePicker from "./GoogleSheetFilePicker";
|
import GoogleSheetFilePicker from "./GoogleSheetFilePicker";
|
||||||
|
import DatasourceInformation from "./../DataSourceEditor/DatasourceSection";
|
||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
interface StateProps extends JSONtoFormProps {
|
interface StateProps extends JSONtoFormProps {
|
||||||
applicationId: string;
|
applicationId: string;
|
||||||
|
|
@ -133,6 +134,13 @@ type State = {
|
||||||
navigation(): void;
|
navigation(): void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ViewModeWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border-bottom: 1px solid #d0d7dd;
|
||||||
|
padding: 24px 20px;
|
||||||
|
`;
|
||||||
|
|
||||||
class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
|
class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
@ -272,6 +280,7 @@ class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
|
||||||
datasourceId,
|
datasourceId,
|
||||||
documentationLink,
|
documentationLink,
|
||||||
featureFlags,
|
featureFlags,
|
||||||
|
formConfig,
|
||||||
formData,
|
formData,
|
||||||
gsheetProjectID,
|
gsheetProjectID,
|
||||||
gsheetToken,
|
gsheetToken,
|
||||||
|
|
@ -410,20 +419,32 @@ class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{viewMode && (
|
{viewMode && (
|
||||||
<Connected
|
<ViewModeWrapper>
|
||||||
errorComponent={
|
<Connected
|
||||||
datasource && isGoogleSheetPlugin && !isPluginAuthorized ? (
|
errorComponent={
|
||||||
<AuthMessage
|
datasource && isGoogleSheetPlugin && !isPluginAuthorized ? (
|
||||||
actionType={ActionType.AUTHORIZE}
|
<AuthMessage
|
||||||
|
actionType="authorize"
|
||||||
|
datasource={datasource}
|
||||||
|
description={authErrorMessage}
|
||||||
|
pageId={pageId}
|
||||||
|
/>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
showDatasourceSavedText={!isGoogleSheetPlugin}
|
||||||
|
/>
|
||||||
|
<div style={{ marginTop: "30px" }}>
|
||||||
|
{!_.isNil(formConfig) &&
|
||||||
|
!_.isNil(datasource) &&
|
||||||
|
!hideDatasourceSection ? (
|
||||||
|
<DatasourceInformation
|
||||||
|
config={formConfig[0]}
|
||||||
datasource={datasource}
|
datasource={datasource}
|
||||||
description={authErrorMessage}
|
viewMode={!!viewMode}
|
||||||
pageId={pageId}
|
|
||||||
/>
|
/>
|
||||||
) : null
|
) : undefined}
|
||||||
}
|
</div>
|
||||||
hideDatasourceRenderSection={hideDatasourceSection}
|
</ViewModeWrapper>
|
||||||
showDatasourceSavedText={!isGoogleSheetPlugin}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
{/* Render datasource form call-to-actions */}
|
{/* Render datasource form call-to-actions */}
|
||||||
{datasource && (
|
{datasource && (
|
||||||
|
|
|
||||||
|
|
@ -1213,7 +1213,8 @@ function* filePickerActionCallbackSaga(
|
||||||
// Once users selects/cancels the file selection,
|
// Once users selects/cancels the file selection,
|
||||||
// Sending sheet ids selected as part of datasource
|
// Sending sheet ids selected as part of datasource
|
||||||
// config properties in order to save it in database
|
// config properties in order to save it in database
|
||||||
set(datasource, "datasourceConfiguration.properties[0]", {
|
// using the second index specifically for file ids.
|
||||||
|
set(datasource, "datasourceConfiguration.properties[1]", {
|
||||||
key: createMessage(GSHEET_AUTHORISED_FILE_IDS_KEY),
|
key: createMessage(GSHEET_AUTHORISED_FILE_IDS_KEY),
|
||||||
value: fileIds,
|
value: fileIds,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import com.appsmith.external.models.DatasourceConfiguration;
|
||||||
public class SheetsUtil {
|
public class SheetsUtil {
|
||||||
|
|
||||||
private static final String FILE_SPECIFIC_DRIVE_SCOPE = "https://www.googleapis.com/auth/drive.file";
|
private static final String FILE_SPECIFIC_DRIVE_SCOPE = "https://www.googleapis.com/auth/drive.file";
|
||||||
|
private static final int USER_AUTHORIZED_SHEET_IDS_INDEX = 1;
|
||||||
static Pattern COLUMN_NAME_PATTERN = Pattern.compile("[a-zA-Z]+");
|
static Pattern COLUMN_NAME_PATTERN = Pattern.compile("[a-zA-Z]+");
|
||||||
|
|
||||||
public static int getColumnNumber(String columnName) {
|
public static int getColumnNumber(String columnName) {
|
||||||
|
|
@ -33,11 +34,11 @@ public class SheetsUtil {
|
||||||
public static Set<String> getUserAuthorizedSheetIds(DatasourceConfiguration datasourceConfiguration) {
|
public static Set<String> getUserAuthorizedSheetIds(DatasourceConfiguration datasourceConfiguration) {
|
||||||
OAuth2 oAuth2 = (OAuth2) datasourceConfiguration.getAuthentication();
|
OAuth2 oAuth2 = (OAuth2) datasourceConfiguration.getAuthentication();
|
||||||
if (!isEmpty(datasourceConfiguration.getProperties())
|
if (!isEmpty(datasourceConfiguration.getProperties())
|
||||||
&& datasourceConfiguration.getProperties().get(0) != null
|
&& datasourceConfiguration.getProperties().get(USER_AUTHORIZED_SHEET_IDS_INDEX) != null
|
||||||
&& datasourceConfiguration.getProperties().get(0).getValue() != null
|
&& datasourceConfiguration.getProperties().get(USER_AUTHORIZED_SHEET_IDS_INDEX).getValue() != null
|
||||||
&& oAuth2.getScope() != null
|
&& oAuth2.getScope() != null
|
||||||
&& oAuth2.getScope().contains(FILE_SPECIFIC_DRIVE_SCOPE)) {
|
&& oAuth2.getScope().contains(FILE_SPECIFIC_DRIVE_SCOPE)) {
|
||||||
ArrayList<String> temp = (ArrayList) datasourceConfiguration.getProperties().get(0).getValue();
|
ArrayList<String> temp = (ArrayList) datasourceConfiguration.getProperties().get(USER_AUTHORIZED_SHEET_IDS_INDEX).getValue();
|
||||||
return new HashSet<String>(temp);
|
return new HashSet<String>(temp);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,17 @@
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"initialValue": "authorization_code"
|
"initialValue": "authorization_code"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": "Account",
|
||||||
|
"configProperty": "datasourceConfiguration.properties[0].value",
|
||||||
|
"controlType": "INPUT_TEXT",
|
||||||
|
"isRequired": false,
|
||||||
|
"hidden": {
|
||||||
|
"comparison": "VIEW_MODE",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
|
"initialValue": "Authorize datasource to fetch account name"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "Permissions | Scope",
|
"label": "Permissions | Scope",
|
||||||
"configProperty": "datasourceConfiguration.authentication.scopeString",
|
"configProperty": "datasourceConfiguration.authentication.scopeString",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user