mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-04-18 03:13:47 +00:00
2️⃣ Add frontend to set authentication providers of a user source
This commit is contained in:
parent
8ac97de75a
commit
d39487e944
22 changed files with 785 additions and 303 deletions
enterprise/web-frontend/modules/baserow_enterprise
assets/scss/components
integrations
appAuthProviderTypes.js
localBaserow/components/appAuthProviders
locales
plugin.jsweb-frontend/modules
builder
core
integrations/localBaserow/components/integrations
|
@ -13,3 +13,4 @@
|
|||
@import 'crud_table_filters';
|
||||
@import 'long_text_field';
|
||||
@import 'highest_role_field';
|
||||
@import 'local_baserow_password_app_auth_provider_form';
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
.local-baserow-password-app-auth-provider-form__field-selector {
|
||||
& .control__label--small {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
& .control__elements {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import { AppAuthProviderType } from '@baserow/modules/core/appAuthProviderTypes'
|
||||
import LocalBaserowUserSourceForm from '@baserow_enterprise/integrations/localBaserow/components/appAuthProviders/LocalBaserowPasswordAppAuthProviderForm'
|
||||
|
||||
export class LocalBaserowPasswordAppAuthProviderType extends AppAuthProviderType {
|
||||
static getType() {
|
||||
return 'local_baserow_password'
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.app.i18n.t('appAuthProviderType.localBaserowPassword')
|
||||
}
|
||||
|
||||
get formComponent() {
|
||||
return LocalBaserowUserSourceForm
|
||||
}
|
||||
|
||||
getOrder() {
|
||||
return 10
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
<template>
|
||||
<form>
|
||||
<FormGroup
|
||||
:label="$t('localBaserowPasswordAppAuthProviderForm.passwordFieldLabel')"
|
||||
small-label
|
||||
horizontal-variable
|
||||
class="local-baserow-password-app-auth-provider-form__field-selector"
|
||||
>
|
||||
<Dropdown
|
||||
v-model="values.password_field_id"
|
||||
fixed-items
|
||||
:disabled="!selectedTable"
|
||||
:placeholder="
|
||||
$t('localBaserowPasswordAppAuthProviderForm.passwordFieldLabel')
|
||||
"
|
||||
>
|
||||
<DropdownItem
|
||||
v-for="field in selectedTable?.fields || []"
|
||||
:key="field.id"
|
||||
:name="field.name"
|
||||
:value="field.id"
|
||||
:icon="getIconForType(field.type)"
|
||||
/>
|
||||
<template #emptyState>
|
||||
{{ $t('localBaserowPasswordAppAuthProviderForm.noFields') }}
|
||||
</template>
|
||||
</Dropdown>
|
||||
</FormGroup>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import form from '@baserow/modules/core/mixins/form'
|
||||
|
||||
export default {
|
||||
mixins: [form],
|
||||
props: {
|
||||
integration: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
currentUserSource: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
values: {
|
||||
password_field_id: null,
|
||||
},
|
||||
allowedValues: ['password_field_id'],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
databases() {
|
||||
return this.integration.context_data.databases
|
||||
},
|
||||
fieldTypes() {
|
||||
return this.$registry.getAll('field')
|
||||
},
|
||||
selectedTable() {
|
||||
if (!this.currentUserSource.table_id) {
|
||||
return null
|
||||
}
|
||||
for (const database of this.databases) {
|
||||
for (const table of database.tables) {
|
||||
if (table.id === this.currentUserSource.table_id) {
|
||||
return table
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'currentUserSource.table_id'() {
|
||||
this.values.password_field_id = null
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getIconForType(type) {
|
||||
return this.fieldTypes[type].getIconClass()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
|
@ -1,295 +1,301 @@
|
|||
{
|
||||
"clientHandler": {
|
||||
"cannotDisableAllAuthProvidersTitle": "Last enabled provider",
|
||||
"cannotDisableAllAuthProvidersDescription": "It is not possible to disable or delete last enabled provider."
|
||||
"clientHandler": {
|
||||
"cannotDisableAllAuthProvidersTitle": "Last enabled provider",
|
||||
"cannotDisableAllAuthProvidersDescription": "It is not possible to disable or delete last enabled provider."
|
||||
},
|
||||
"enterprise": {
|
||||
"license": "Enterprise",
|
||||
"sidebarTooltip": "Your account has access to the enterprise features globally",
|
||||
"rbac": "RBAC",
|
||||
"sso": "SSO",
|
||||
"deactivated": "Available in advanced/enterprise",
|
||||
"licenseDescription": "Viewers are free with Baserow Enterprise. If a user has any other role, in any workspace then they will use a paid seat automatically.",
|
||||
"overflowWarning": "You have too many non-viewer users and have used up all of your paid seats. Change users to become viewers on each workspaces members page."
|
||||
},
|
||||
"trashType": {
|
||||
"team": "team"
|
||||
},
|
||||
"createTeamModal": {
|
||||
"title": "Create team",
|
||||
"invalidNameTitle": "Please use a different name",
|
||||
"invalidNameMessage": "This team name is already in use in the specified workspace."
|
||||
},
|
||||
"updateTeamModal": {
|
||||
"title": "Update {teamName}",
|
||||
"invalidNameTitle": "Please use a different name",
|
||||
"invalidNameMessage": "This team name is already in use in the specified workspace."
|
||||
},
|
||||
"manageTeamModals": {
|
||||
"subheading": "Teams allow you to give or restrict permissions in bulk to multiple people."
|
||||
},
|
||||
"manageTeamForm": {
|
||||
"submit": "Save",
|
||||
"nameTitle": "Name",
|
||||
"roleTitle": "Default role",
|
||||
"inviteMembers": "Add members",
|
||||
"membersTitle": "Members",
|
||||
"noSubjectsSelected": "Click '{buttonLabel}' to optionally add team users.",
|
||||
"roleHelpText": "User specific roles will always override Team roles."
|
||||
},
|
||||
"editTeamContext": {
|
||||
"edit": "Edit team",
|
||||
"remove": "Delete team"
|
||||
},
|
||||
"teamsTable": {
|
||||
"title": "{teamCount} teams in {workspaceName}",
|
||||
"createNew": "Create team",
|
||||
"nameColumn": "Name",
|
||||
"createdColumn": "Created on",
|
||||
"subjectsColumn": "Members",
|
||||
"roleColumn": "Default role",
|
||||
"roleHelpText": "Can be overriden with roles on databases and tables."
|
||||
},
|
||||
"subjectSampleField": {
|
||||
"titleAttr": "{subjectCount} members in this team."
|
||||
},
|
||||
"teamsSettings": {
|
||||
"teamsTabTitle": "Teams"
|
||||
},
|
||||
"adminType": {
|
||||
"AuditLog": "Audit log",
|
||||
"Authentication": "Authentication"
|
||||
},
|
||||
"auditLog": {
|
||||
"adminTitle": "Audit log",
|
||||
"workspaceTitle": "Audit log - {workspaceName}",
|
||||
"filterUserTitle": "User",
|
||||
"filterWorkspaceTitle": "Workspace",
|
||||
"filterActionTypeTitle": "Event Type",
|
||||
"filterFromTimestampTitle": "From Date",
|
||||
"filterFromTimestamp": "From Date",
|
||||
"filterToTimestampTitle": "To Date",
|
||||
"filterToTimestamp": "To Date",
|
||||
"user": "User",
|
||||
"workspace": "Workspace",
|
||||
"actionType": "Event Type",
|
||||
"description": "Description",
|
||||
"timestamp": "Timestamp",
|
||||
"ip_address": "IP Address",
|
||||
"exportToCsv": "Export to CSV",
|
||||
"exportModalTitle": "Export to CSV",
|
||||
"clearFilters": "Clear",
|
||||
"allUsers": "All Users",
|
||||
"allWorkspaces": "All Workspaces",
|
||||
"allActionTypes": "All Event Types"
|
||||
},
|
||||
"auditLogExportModal": {
|
||||
"title": "Export to CSV",
|
||||
"exportFilename": "Admin Audit Log Export - {date}",
|
||||
"exportWorkspaceFilename": " Workspace ({workspaceId}) Audit Log Export - {date}",
|
||||
"cancelledTitle": "Export failed",
|
||||
"cancelledDescription": "Something went wrong while exporting the audit log. Please try again."
|
||||
},
|
||||
"authProviders": {
|
||||
"title": "Authentication Providers",
|
||||
"noProviders": "No authentication providers configured yet.",
|
||||
"addProvider": "Add provider"
|
||||
},
|
||||
"authProviderTypes": {
|
||||
"password": "Email and password authentication"
|
||||
},
|
||||
"editAuthProviderMenuContext": {
|
||||
"edit": "Edit",
|
||||
"delete": "Delete"
|
||||
},
|
||||
"samlSettingsForm": {
|
||||
"domain": "Domain",
|
||||
"domainPlaceholder": "Insert the company domain name...",
|
||||
"invalidDomain": "Invalid domain name",
|
||||
"domainAlreadyExists": "A SAML provider for this domain already exists",
|
||||
"metadata": "Metadata",
|
||||
"metadataPlaceholder": "Paste the Identity Provider metadata...",
|
||||
"invalidMetadata": "Invalid XML metadata for the Identity Provider",
|
||||
"relayStateUrl": "Default Relay State URL",
|
||||
"acsUrl": "Single Sign On URL",
|
||||
"providerIsVerified": "The provider has been verified"
|
||||
},
|
||||
"createSettingsAuthProviderModal": {
|
||||
"title": "Add a new {type}"
|
||||
},
|
||||
"updateSettingsAuthProviderModal": {
|
||||
"title": "Edit {name}"
|
||||
},
|
||||
"deleteAuthProviderModal": {
|
||||
"title": "Delete {name}",
|
||||
"comment": "Do you really want to delete this {type}?"
|
||||
},
|
||||
"loginWithSaml": {
|
||||
"signInWithSaml": "Login with SAML SSO",
|
||||
"redirecting": "Redirecting to the Identity Provider...",
|
||||
"continueWithSaml": "Continue to the SAML SSO provider",
|
||||
"requestError": "This domain is not configured with SAML SSO",
|
||||
"loginText": "Already have a password?"
|
||||
},
|
||||
"loginError": {
|
||||
"title": "Something went wrong:",
|
||||
"loginText": "Already have an account?",
|
||||
"help": "Please contact your administrator for help.",
|
||||
"defaultErrorMessage": "it was not possible to complete the SSO login flow.",
|
||||
"errorSsoFeatureNotActive": "SSO feature is not active. Please contact your administrator.",
|
||||
"errorInvalidSamlRequest": "SAML request is invalid.",
|
||||
"errorInvalidSamlResponse": "SAML response is invalid.",
|
||||
"errorUserDeactivated": "user has been disabled.",
|
||||
"errorProviderDoesNotExist": "this authentication provider doesn't exist or is not available.",
|
||||
"errorAuthFlowError": "an error occurred during the authentication flow with the selected provider.",
|
||||
"errorDifferentProvider": "please use the provider that you originally signed up with.",
|
||||
"errorWorkspaceInvitationEmailMismatch": "your email address does not match with the invitation.",
|
||||
"errorSignupDisabled": "sign up has been disabled by the administrator."
|
||||
},
|
||||
"roles": {
|
||||
"admin": {
|
||||
"name": "Admin",
|
||||
"description": "Can fully configure and edit workspaces and applications."
|
||||
},
|
||||
"enterprise": {
|
||||
"license": "Enterprise",
|
||||
"sidebarTooltip": "Your account has access to the enterprise features globally",
|
||||
"rbac": "RBAC",
|
||||
"sso": "SSO",
|
||||
"deactivated": "Available in advanced/enterprise",
|
||||
"licenseDescription": "Viewers are free with Baserow Enterprise. If a user has any other role, in any workspace then they will use a paid seat automatically.",
|
||||
"overflowWarning": "You have too many non-viewer users and have used up all of your paid seats. Change users to become viewers on each workspaces members page."
|
||||
"builder": {
|
||||
"name": "Builder",
|
||||
"description": "Can fully configure and edit applications."
|
||||
},
|
||||
"trashType": {
|
||||
"team": "team"
|
||||
"editor": {
|
||||
"name": "Editor",
|
||||
"description": "Can fully edit data but not configure applications or workspaces."
|
||||
},
|
||||
"createTeamModal": {
|
||||
"title": "Create team",
|
||||
"invalidNameTitle": "Please use a different name",
|
||||
"invalidNameMessage": "This team name is already in use in the specified workspace."
|
||||
"commenter": {
|
||||
"name": "Commenter",
|
||||
"description": "Can only read and comment on data."
|
||||
},
|
||||
"updateTeamModal": {
|
||||
"title": "Update {teamName}",
|
||||
"invalidNameTitle": "Please use a different name",
|
||||
"invalidNameMessage": "This team name is already in use in the specified workspace."
|
||||
"viewer": {
|
||||
"name": "Viewer",
|
||||
"description": "Can only read data."
|
||||
},
|
||||
"manageTeamModals": {
|
||||
"subheading": "Teams allow you to give or restrict permissions in bulk to multiple people."
|
||||
"noAccess": {
|
||||
"name": "No access",
|
||||
"description": "Can't access anything."
|
||||
},
|
||||
"manageTeamForm": {
|
||||
"submit": "Save",
|
||||
"nameTitle": "Name",
|
||||
"roleTitle": "Default role",
|
||||
"inviteMembers": "Add members",
|
||||
"membersTitle": "Members",
|
||||
"noSubjectsSelected": "Click '{buttonLabel}' to optionally add team users.",
|
||||
"roleHelpText": "User specific roles will always override Team roles."
|
||||
},
|
||||
"editTeamContext": {
|
||||
"edit": "Edit team",
|
||||
"remove": "Delete team"
|
||||
},
|
||||
"teamsTable": {
|
||||
"title": "{teamCount} teams in {workspaceName}",
|
||||
"createNew": "Create team",
|
||||
"nameColumn": "Name",
|
||||
"createdColumn": "Created on",
|
||||
"subjectsColumn": "Members",
|
||||
"roleColumn": "Default role",
|
||||
"roleHelpText": "Can be overriden with roles on databases and tables."
|
||||
},
|
||||
"subjectSampleField": {
|
||||
"titleAttr": "{subjectCount} members in this team."
|
||||
},
|
||||
"teamsSettings": {
|
||||
"teamsTabTitle": "Teams"
|
||||
},
|
||||
"adminType": {
|
||||
"AuditLog": "Audit log",
|
||||
"Authentication": "Authentication"
|
||||
},
|
||||
"auditLog": {
|
||||
"adminTitle": "Audit log",
|
||||
"workspaceTitle": "Audit log - {workspaceName}",
|
||||
"filterUserTitle": "User",
|
||||
"filterWorkspaceTitle": "Workspace",
|
||||
"filterActionTypeTitle": "Event Type",
|
||||
"filterFromTimestampTitle": "From Date",
|
||||
"filterFromTimestamp": "From Date",
|
||||
"filterToTimestampTitle": "To Date",
|
||||
"filterToTimestamp": "To Date",
|
||||
"user": "User",
|
||||
"workspace": "Workspace",
|
||||
"actionType": "Event Type",
|
||||
"description": "Description",
|
||||
"timestamp": "Timestamp",
|
||||
"ip_address": "IP Address",
|
||||
"exportToCsv": "Export to CSV",
|
||||
"exportModalTitle": "Export to CSV",
|
||||
"clearFilters": "Clear",
|
||||
"allUsers": "All Users",
|
||||
"allWorkspaces": "All Workspaces",
|
||||
"allActionTypes": "All Event Types"
|
||||
},
|
||||
"auditLogExportModal": {
|
||||
"title": "Export to CSV",
|
||||
"exportFilename": "Admin Audit Log Export - {date}",
|
||||
"exportWorkspaceFilename": " Workspace ({workspaceId}) Audit Log Export - {date}",
|
||||
"cancelledTitle": "Export failed",
|
||||
"cancelledDescription": "Something went wrong while exporting the audit log. Please try again."
|
||||
},
|
||||
"authProviders": {
|
||||
"title": "Authentication Providers",
|
||||
"noProviders": "No authentication providers configured yet.",
|
||||
"addProvider": "Add provider"
|
||||
},
|
||||
"authProviderTypes": {
|
||||
"password": "Email and password authentication"
|
||||
},
|
||||
"editAuthProviderMenuContext": {
|
||||
"edit": "Edit",
|
||||
"delete": "Delete"
|
||||
},
|
||||
"samlSettingsForm": {
|
||||
"domain": "Domain",
|
||||
"domainPlaceholder": "Insert the company domain name...",
|
||||
"invalidDomain": "Invalid domain name",
|
||||
"domainAlreadyExists": "A SAML provider for this domain already exists",
|
||||
"metadata": "Metadata",
|
||||
"metadataPlaceholder": "Paste the Identity Provider metadata...",
|
||||
"invalidMetadata": "Invalid XML metadata for the Identity Provider",
|
||||
"relayStateUrl": "Default Relay State URL",
|
||||
"acsUrl": "Single Sign On URL",
|
||||
"providerIsVerified": "The provider has been verified"
|
||||
},
|
||||
"createSettingsAuthProviderModal": {
|
||||
"title": "Add a new {type}"
|
||||
},
|
||||
"updateSettingsAuthProviderModal": {
|
||||
"title": "Edit {name}"
|
||||
},
|
||||
"deleteAuthProviderModal": {
|
||||
"title": "Delete {name}",
|
||||
"comment": "Do you really want to delete this {type}?"
|
||||
},
|
||||
"loginWithSaml": {
|
||||
"signInWithSaml": "Login with SAML SSO",
|
||||
"redirecting": "Redirecting to the Identity Provider...",
|
||||
"continueWithSaml": "Continue to the SAML SSO provider",
|
||||
"requestError": "This domain is not configured with SAML SSO",
|
||||
"loginText": "Already have a password?"
|
||||
},
|
||||
"loginError": {
|
||||
"title": "Something went wrong:",
|
||||
"loginText": "Already have an account?",
|
||||
"help": "Please contact your administrator for help.",
|
||||
"defaultErrorMessage": "it was not possible to complete the SSO login flow.",
|
||||
"errorSsoFeatureNotActive": "SSO feature is not active. Please contact your administrator.",
|
||||
"errorInvalidSamlRequest": "SAML request is invalid.",
|
||||
"errorInvalidSamlResponse": "SAML response is invalid.",
|
||||
"errorUserDeactivated": "user has been disabled.",
|
||||
"errorProviderDoesNotExist": "this authentication provider doesn't exist or is not available.",
|
||||
"errorAuthFlowError": "an error occurred during the authentication flow with the selected provider.",
|
||||
"errorDifferentProvider": "please use the provider that you originally signed up with.",
|
||||
"errorWorkspaceInvitationEmailMismatch": "your email address does not match with the invitation.",
|
||||
"errorSignupDisabled": "sign up has been disabled by the administrator."
|
||||
},
|
||||
"roles": {
|
||||
"admin": {
|
||||
"name": "Admin",
|
||||
"description": "Can fully configure and edit workspaces and applications."
|
||||
},
|
||||
"builder": {
|
||||
"name": "Builder",
|
||||
"description": "Can fully configure and edit applications."
|
||||
},
|
||||
"editor": {
|
||||
"name": "Editor",
|
||||
"description": "Can fully edit data but not configure applications or workspaces."
|
||||
},
|
||||
"commenter": {
|
||||
"name": "Commenter",
|
||||
"description": "Can only read and comment on data."
|
||||
},
|
||||
"viewer": {
|
||||
"name": "Viewer",
|
||||
"description": "Can only read data."
|
||||
},
|
||||
"noAccess": {
|
||||
"name": "No access",
|
||||
"description": "Can't access anything."
|
||||
},
|
||||
"noRoleLowPriority": {
|
||||
"name": "No role",
|
||||
"description": "Get default workspace role from their teams."
|
||||
}
|
||||
},
|
||||
"memberRolesModal": {
|
||||
"memberRolesDatabaseTabTitle": "Database",
|
||||
"memberRolesTableTabTitle": "Current Table",
|
||||
"error": {
|
||||
"title": "Could not fetch data",
|
||||
"description": "An error occurred while fetching the member data."
|
||||
}
|
||||
},
|
||||
"memberRolesTab": {
|
||||
"database": {
|
||||
"title": "{name} database",
|
||||
"selectMembers": "Select members",
|
||||
"everyoneHasAccess": "Everyone at {name} workspace can access this database.",
|
||||
"onlyYouHaveAccess": "Only you can access this database.",
|
||||
"warningTitle": "Other users might inherit access!",
|
||||
"warningMessage": "Other users might inherit access via their respective roles on the parent workspace.",
|
||||
"headerTooltip": "Database roles will override workspace roles."
|
||||
},
|
||||
"table": {
|
||||
"title": "{name} table",
|
||||
"selectMembers": "Select members",
|
||||
"everyoneHasAccess": "Everyone at {name} workspace can access this table.",
|
||||
"onlyYouHaveAccess": "Only you can access this table.",
|
||||
"warningTitle": "Other users might inherit access!",
|
||||
"warningMessage": "Other users might inherit access via their respective roles on the parent database or workspace.",
|
||||
"headerTooltip": "Table roles will override workspace and database roles."
|
||||
}
|
||||
},
|
||||
"memberRolesShareToggle": {
|
||||
"label": "Share with everyone at {name}",
|
||||
"subLabel": "{totalUserAmount} workspace members"
|
||||
},
|
||||
"memberRolesDatabaseContexItem": {
|
||||
"label": "Manage members"
|
||||
},
|
||||
"memberRolesTableContexItem": {
|
||||
"label": "Manage members"
|
||||
},
|
||||
"memberRolesMembersList": {
|
||||
"remove": "Remove",
|
||||
"teamMembersCount": "{count} team members",
|
||||
"adminHelpText": "Admins can restrict other admins roles.",
|
||||
"noMembers": "No members have been selected. Use the select button to add one."
|
||||
},
|
||||
"roleAssignmentModal": {
|
||||
"membersTab": "Members",
|
||||
"teamsTab": "Teams",
|
||||
"subjectTypeNameMembers": "members",
|
||||
"subjectTypeNameTeams": "teams"
|
||||
},
|
||||
"selectMembersList": {
|
||||
"searchPlaceholder": "Find members...",
|
||||
"selectedAmountLabel": "{count} members selected"
|
||||
},
|
||||
"selectTeamsList": {
|
||||
"searchPlaceholder": "Find teams...",
|
||||
"selectedAmountLabel": "{count} teams selected"
|
||||
},
|
||||
"selectSubjectsListFooter": {
|
||||
"invite": "Invite {count} {type}",
|
||||
"types": {
|
||||
"members": "members",
|
||||
"teams": "teams"
|
||||
},
|
||||
"helpTooltip": "Member role assignments override team role assignments."
|
||||
},
|
||||
"membersRoleField": {
|
||||
"noAccessHelpText": "This user requires explicit access to resources.",
|
||||
"adminHelpText": "Admins can restrict other admins roles."
|
||||
},
|
||||
"membersPagePlugin": {
|
||||
"roleHelpText": "Can be overriden with roles on databases and tables."
|
||||
},
|
||||
"oauthSettingsForm": {
|
||||
"providerName": "Name",
|
||||
"providerNamePlaceholder": "Custom provider name",
|
||||
"clientId": "Client ID",
|
||||
"clientIdPlaceholder": "Provider's client ID",
|
||||
"secret": "Secret",
|
||||
"secretPlaceholder": "Provider's secret",
|
||||
"baseUrl": "URL",
|
||||
"baseUrlPlaceholder": "Provider's base URL",
|
||||
"invalidBaseUrl": "The entered URL is not a valid provider URL",
|
||||
"callbackUrl": "Callback URL"
|
||||
},
|
||||
"loginButton": {
|
||||
"continueWith": "Continue with"
|
||||
},
|
||||
"enterpriseFeatures": {
|
||||
"sso": "Single Sign On",
|
||||
"rbac": "Role-based access control"
|
||||
},
|
||||
"chatwootSupportSidebarWorkspace": {
|
||||
"directSupport": "Direct support"
|
||||
},
|
||||
"userTeamsField": {
|
||||
"no_records": "No teams"
|
||||
},
|
||||
"snapshotModalWarning": {
|
||||
"message": "Please be aware that a snapshot will include any permissions set on the application and its tables."
|
||||
},
|
||||
"auditLogSidebarWorkspace": {
|
||||
"title": "Audit log",
|
||||
"deactivated": "Available in advanced/enterprise"
|
||||
},
|
||||
"localBaserowUserSourceType": {
|
||||
"notConfigured": "Not configured"
|
||||
},
|
||||
"localBaserowUserSourceForm": {
|
||||
"description": "Every row in the table is a user account. Please select the matching fields in the table. The email field will be used to identify.",
|
||||
"emailFieldLabel": "Select email field",
|
||||
"emailFieldLabelPlaceholder": "Select a field...",
|
||||
"noFields": "No fields",
|
||||
"nameFieldLabel": "Select name field",
|
||||
"nameFieldPlaceholder": "Select a field..."
|
||||
"noRoleLowPriority": {
|
||||
"name": "No role",
|
||||
"description": "Get default workspace role from their teams."
|
||||
}
|
||||
},
|
||||
"memberRolesModal": {
|
||||
"memberRolesDatabaseTabTitle": "Database",
|
||||
"memberRolesTableTabTitle": "Current Table",
|
||||
"error": {
|
||||
"title": "Could not fetch data",
|
||||
"description": "An error occurred while fetching the member data."
|
||||
}
|
||||
},
|
||||
"memberRolesTab": {
|
||||
"database": {
|
||||
"title": "{name} database",
|
||||
"selectMembers": "Select members",
|
||||
"everyoneHasAccess": "Everyone at {name} workspace can access this database.",
|
||||
"onlyYouHaveAccess": "Only you can access this database.",
|
||||
"warningTitle": "Other users might inherit access!",
|
||||
"warningMessage": "Other users might inherit access via their respective roles on the parent workspace.",
|
||||
"headerTooltip": "Database roles will override workspace roles."
|
||||
},
|
||||
"table": {
|
||||
"title": "{name} table",
|
||||
"selectMembers": "Select members",
|
||||
"everyoneHasAccess": "Everyone at {name} workspace can access this table.",
|
||||
"onlyYouHaveAccess": "Only you can access this table.",
|
||||
"warningTitle": "Other users might inherit access!",
|
||||
"warningMessage": "Other users might inherit access via their respective roles on the parent database or workspace.",
|
||||
"headerTooltip": "Table roles will override workspace and database roles."
|
||||
}
|
||||
},
|
||||
"memberRolesShareToggle": {
|
||||
"label": "Share with everyone at {name}",
|
||||
"subLabel": "{totalUserAmount} workspace members"
|
||||
},
|
||||
"memberRolesDatabaseContexItem": {
|
||||
"label": "Manage members"
|
||||
},
|
||||
"memberRolesTableContexItem": {
|
||||
"label": "Manage members"
|
||||
},
|
||||
"memberRolesMembersList": {
|
||||
"remove": "Remove",
|
||||
"teamMembersCount": "{count} team members",
|
||||
"adminHelpText": "Admins can restrict other admins roles.",
|
||||
"noMembers": "No members have been selected. Use the select button to add one."
|
||||
},
|
||||
"roleAssignmentModal": {
|
||||
"membersTab": "Members",
|
||||
"teamsTab": "Teams",
|
||||
"subjectTypeNameMembers": "members",
|
||||
"subjectTypeNameTeams": "teams"
|
||||
},
|
||||
"selectMembersList": {
|
||||
"searchPlaceholder": "Find members...",
|
||||
"selectedAmountLabel": "{count} members selected"
|
||||
},
|
||||
"selectTeamsList": {
|
||||
"searchPlaceholder": "Find teams...",
|
||||
"selectedAmountLabel": "{count} teams selected"
|
||||
},
|
||||
"selectSubjectsListFooter": {
|
||||
"invite": "Invite {count} {type}",
|
||||
"types": {
|
||||
"members": "members",
|
||||
"teams": "teams"
|
||||
},
|
||||
"helpTooltip": "Member role assignments override team role assignments."
|
||||
},
|
||||
"membersRoleField": {
|
||||
"noAccessHelpText": "This user requires explicit access to resources.",
|
||||
"adminHelpText": "Admins can restrict other admins roles."
|
||||
},
|
||||
"membersPagePlugin": {
|
||||
"roleHelpText": "Can be overriden with roles on databases and tables."
|
||||
},
|
||||
"oauthSettingsForm": {
|
||||
"providerName": "Name",
|
||||
"providerNamePlaceholder": "Custom provider name",
|
||||
"clientId": "Client ID",
|
||||
"clientIdPlaceholder": "Provider's client ID",
|
||||
"secret": "Secret",
|
||||
"secretPlaceholder": "Provider's secret",
|
||||
"baseUrl": "URL",
|
||||
"baseUrlPlaceholder": "Provider's base URL",
|
||||
"invalidBaseUrl": "The entered URL is not a valid provider URL",
|
||||
"callbackUrl": "Callback URL"
|
||||
},
|
||||
"loginButton": {
|
||||
"continueWith": "Continue with"
|
||||
},
|
||||
"enterpriseFeatures": {
|
||||
"sso": "Single Sign On",
|
||||
"rbac": "Role-based access control"
|
||||
},
|
||||
"chatwootSupportSidebarWorkspace": {
|
||||
"directSupport": "Direct support"
|
||||
},
|
||||
"userTeamsField": {
|
||||
"no_records": "No teams"
|
||||
},
|
||||
"snapshotModalWarning": {
|
||||
"message": "Please be aware that a snapshot will include any permissions set on the application and its tables."
|
||||
},
|
||||
"auditLogSidebarWorkspace": {
|
||||
"title": "Audit log",
|
||||
"deactivated": "Available in advanced/enterprise"
|
||||
},
|
||||
"localBaserowUserSourceType": {
|
||||
"notConfigured": "Not configured"
|
||||
},
|
||||
"localBaserowUserSourceForm": {
|
||||
"description": "Every row in the table is a user account. Please select the matching fields in the table. The email field will be used to identify.",
|
||||
"emailFieldLabel": "Select email field",
|
||||
"emailFieldLabelPlaceholder": "Select a field...",
|
||||
"noFields": "No fields",
|
||||
"nameFieldLabel": "Select name field",
|
||||
"nameFieldPlaceholder": "Select a field..."
|
||||
},
|
||||
"appAuthProviderType": {
|
||||
"localBaserowPassword": "Email/Password"
|
||||
},
|
||||
"localBaserowPasswordAppAuthProviderForm": {
|
||||
"passwordFieldLabel": "Select password field"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import {
|
|||
} from '@baserow_enterprise/licenseTypes'
|
||||
import { EnterprisePlugin } from '@baserow_enterprise/plugins'
|
||||
import { LocalBaserowUserSourceType } from '@baserow_enterprise/integrations/userSourceTypes'
|
||||
import { LocalBaserowPasswordAppAuthProviderType } from '@baserow_enterprise/integrations/appAuthProviderTypes'
|
||||
|
||||
export default (context) => {
|
||||
const { app, isDev, store } = context
|
||||
|
@ -89,4 +90,9 @@ export default (context) => {
|
|||
app.$registry.register('license', new EnterpriseLicenseType(context))
|
||||
|
||||
app.$registry.register('userSource', new LocalBaserowUserSourceType(context))
|
||||
|
||||
app.$registry.register(
|
||||
'appAuthProvider',
|
||||
new LocalBaserowPasswordAppAuthProviderType(context)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -242,7 +242,6 @@ export default {
|
|||
})
|
||||
},
|
||||
changeFieldType(fieldToUpdate, newType) {
|
||||
console.log('newType', newType)
|
||||
this.values.fields = this.values.fields.map((field) => {
|
||||
if (field.id === fieldToUpdate.id) {
|
||||
return { id: field.id, name: field.name, type: newType }
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
:image="getIntegrationType(integration).image"
|
||||
:title="integration.name"
|
||||
:subtitle="getIntegrationType(integration).getSummary(integration)"
|
||||
avatar-color="ghost"
|
||||
avatar-color="transparent"
|
||||
style="flex: 1"
|
||||
/>
|
||||
<div class="integration_settings__integration-actions">
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
:image="getUserSourceType(userSource).image"
|
||||
:title="userSource.name"
|
||||
:subtitle="getUserSourceType(userSource).getSummary(userSource)"
|
||||
avatar-color="ghost"
|
||||
avatar-color="transparent"
|
||||
style="flex: 1"
|
||||
/>
|
||||
<div class="user-source-settings__user-source-actions">
|
||||
|
@ -60,9 +60,9 @@
|
|||
<Presentation
|
||||
:image="getUserSourceType(editedUserSource).image"
|
||||
:title="getUserSourceType(editedUserSource).name"
|
||||
avatar-color="ghost"
|
||||
avatar-color="transparent"
|
||||
style="flex: 1; margin-bottom: 18px"
|
||||
icon-size="tiny"
|
||||
icon-size="medium"
|
||||
/>
|
||||
|
||||
<UpdateUserSourceForm
|
||||
|
|
|
@ -26,7 +26,35 @@
|
|||
:default-values="defaultValues"
|
||||
:application="builder"
|
||||
:integration="integration"
|
||||
@values-changed="emitChange"
|
||||
/>
|
||||
<div v-if="integration">
|
||||
<h4>{{ $t('updateUserSourceForm.authTitle') }}</h4>
|
||||
|
||||
<div v-for="appAuthType in appAuthProviderTypes" :key="appAuthType.type">
|
||||
<Checkbox
|
||||
:checked="hasAtLeastOneOfThisType(appAuthType)"
|
||||
@input="onSelect(appAuthType)"
|
||||
>
|
||||
{{ appAuthType.name }}
|
||||
</Checkbox>
|
||||
<div
|
||||
v-for="appAuthProvider in appAuthProviderPerTypes[appAuthType.type]"
|
||||
:key="appAuthProvider.id"
|
||||
class="update-user-source-form__auth-provider-form"
|
||||
>
|
||||
<component
|
||||
:is="appAuthType.formComponent"
|
||||
v-if="hasAtLeastOneOfThisType(appAuthType)"
|
||||
:integration="integration"
|
||||
:current-user-source="fullValues"
|
||||
:default-values="appAuthProvider"
|
||||
excluded-form
|
||||
@values-changed="updateAuthProvider(appAuthProvider, $event)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
|
@ -34,6 +62,7 @@
|
|||
import form from '@baserow/modules/core/mixins/form'
|
||||
import IntegrationDropdown from '@baserow/modules/core/components/integrations/IntegrationDropdown'
|
||||
import { required, maxLength } from 'vuelidate/lib/validators'
|
||||
import { uuid } from '@baserow/modules/core/utils/string'
|
||||
|
||||
export default {
|
||||
components: { IntegrationDropdown },
|
||||
|
@ -58,8 +87,9 @@ export default {
|
|||
values: {
|
||||
integration_id: null,
|
||||
name: '',
|
||||
auth_providers: [],
|
||||
},
|
||||
allowedValues: ['integration_id', 'name'],
|
||||
fullValues: this.getFormValues(),
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -71,8 +101,67 @@ export default {
|
|||
({ id }) => id === this.values.integration_id
|
||||
)
|
||||
},
|
||||
appAuthProviderTypes() {
|
||||
return this.$registry.getOrderedList('appAuthProvider')
|
||||
},
|
||||
appAuthProviderPerTypes() {
|
||||
return Object.fromEntries(
|
||||
this.appAuthProviderTypes.map((authType) => {
|
||||
return [
|
||||
authType.type,
|
||||
this.values.auth_providers.filter(
|
||||
({ type }) => type === authType.type
|
||||
),
|
||||
]
|
||||
})
|
||||
)
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// Override the default getChildFormValues to exclude the provider forms from
|
||||
// final values as they are handled directly by this component
|
||||
getChildFormsValues() {
|
||||
return Object.assign(
|
||||
{},
|
||||
...this.$children
|
||||
.filter(
|
||||
(child) =>
|
||||
'getChildFormsValues' in child &&
|
||||
child.$attrs['excluded-form'] === undefined
|
||||
)
|
||||
.map((child) => {
|
||||
return child.getFormValues()
|
||||
})
|
||||
)
|
||||
},
|
||||
hasAtLeastOneOfThisType(appAuthProviderType) {
|
||||
return this.appAuthProviderPerTypes[appAuthProviderType.type]?.length > 0
|
||||
},
|
||||
onSelect(appAuthProviderType) {
|
||||
if (this.hasAtLeastOneOfThisType(appAuthProviderType)) {
|
||||
this.values.auth_providers = this.values.auth_providers.filter(
|
||||
({ type }) => type !== appAuthProviderType.type
|
||||
)
|
||||
} else {
|
||||
this.values.auth_providers.push({
|
||||
type: appAuthProviderType.type,
|
||||
id: uuid(),
|
||||
})
|
||||
}
|
||||
},
|
||||
updateAuthProvider(authProviderToChange, values) {
|
||||
this.values.auth_providers = this.values.auth_providers.map(
|
||||
(authProvider) => {
|
||||
if (authProvider.id === authProviderToChange.id) {
|
||||
return { ...authProvider, ...values }
|
||||
}
|
||||
return authProvider
|
||||
}
|
||||
)
|
||||
},
|
||||
emitChange() {
|
||||
this.fullValues = this.getFormValues()
|
||||
},
|
||||
getError(fieldName) {
|
||||
if (!this.$v.values[fieldName].$dirty) {
|
||||
return ''
|
||||
|
|
|
@ -440,6 +440,7 @@
|
|||
"updateUserSourceForm": {
|
||||
"nameFieldLabel": "Name",
|
||||
"nameFieldPlaceholder": "Enter a name...",
|
||||
"authTitle": "Authentication",
|
||||
"integrationFieldLabel": "Integration"
|
||||
},
|
||||
"formContainerElementForm": {
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
DomainsBuilderSettingsType,
|
||||
IntegrationsBuilderSettingsType,
|
||||
ThemeBuilderSettingsType,
|
||||
UserSourcesBuilderSettingsType,
|
||||
} from '@baserow/modules/builder/builderSettingTypes'
|
||||
|
||||
import pageStore from '@baserow/modules/builder/store/page'
|
||||
|
@ -150,6 +151,13 @@ export default (context) => {
|
|||
new DomainsBuilderSettingsType(context)
|
||||
)
|
||||
|
||||
if (app.$featureFlagIsEnabled('builder-user-source')) {
|
||||
app.$registry.register(
|
||||
'builderSettings',
|
||||
new UserSourcesBuilderSettingsType(context)
|
||||
)
|
||||
}
|
||||
|
||||
app.$registry.register('errorPage', new PublicSiteErrorPageType(context))
|
||||
|
||||
app.$registry.register('element', new HeadingElementType(context))
|
||||
|
|
18
web-frontend/modules/core/appAuthProviderTypes.js
Normal file
18
web-frontend/modules/core/appAuthProviderTypes.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { Registerable } from '@baserow/modules/core/registry'
|
||||
|
||||
export class AppAuthProviderType extends Registerable {
|
||||
get name() {
|
||||
throw new Error('Must be set on the type.')
|
||||
}
|
||||
|
||||
/**
|
||||
* The form to edit this user source.
|
||||
*/
|
||||
get formComponent() {
|
||||
return null
|
||||
}
|
||||
|
||||
getOrder() {
|
||||
return 0
|
||||
}
|
||||
}
|
|
@ -26,3 +26,4 @@
|
|||
@import 'workflow_action_selector';
|
||||
@import 'user_source_settings';
|
||||
@import 'loading_spinner';
|
||||
@import 'update_user_source_form';
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
.update-user-source-form__auth-provider-form {
|
||||
margin-left: 24px;
|
||||
}
|
|
@ -59,8 +59,10 @@ export default {
|
|||
required: false,
|
||||
type: String,
|
||||
default: 'blue',
|
||||
validator: function (value) {
|
||||
validator(value) {
|
||||
return [
|
||||
null,
|
||||
undefined,
|
||||
'blue',
|
||||
'cyan',
|
||||
'green',
|
||||
|
@ -80,7 +82,7 @@ export default {
|
|||
type: String,
|
||||
required: false,
|
||||
default: 'medium',
|
||||
validator: function (value) {
|
||||
validator(value) {
|
||||
return ['small', 'medium', 'large', 'x-large'].includes(value)
|
||||
},
|
||||
},
|
||||
|
|
|
@ -26,7 +26,7 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
Object.assign(this.values, this.values, this.getDefaultValues())
|
||||
this.values = Object.assign({}, this.values, this.getDefaultValues())
|
||||
},
|
||||
watch: {
|
||||
values: {
|
||||
|
@ -132,7 +132,8 @@ export default {
|
|||
* calling the submitted event.
|
||||
*/
|
||||
getFormValues() {
|
||||
return Object.assign({}, this.values, this.getChildFormsValues())
|
||||
const result = Object.assign({}, this.values, this.getChildFormsValues())
|
||||
return result
|
||||
},
|
||||
/**
|
||||
* Returns an object containing the values of the child forms.
|
||||
|
|
|
@ -52,6 +52,7 @@ import sidebarStore from '@baserow/modules/core/store/sidebar'
|
|||
import undoRedoStore from '@baserow/modules/core/store/undoRedo'
|
||||
import integrationStore from '@baserow/modules/core/store/integration'
|
||||
import userSourceStore from '@baserow/modules/core/store/userSource'
|
||||
import appAuthProviderStore from '@baserow/modules/core/store/appAuthProvider'
|
||||
import notificationStore from '@baserow/modules/core/store/notification'
|
||||
|
||||
import en from '@baserow/modules/core/locales/en.json'
|
||||
|
@ -101,6 +102,11 @@ export default (context, inject) => {
|
|||
registry.registerNamespace('runtimeFormulaFunction')
|
||||
registry.registerNamespace('notification')
|
||||
registry.registerNamespace('workflowAction')
|
||||
registry.registerNamespace('integration')
|
||||
registry.registerNamespace('service')
|
||||
registry.registerNamespace('userSource')
|
||||
registry.registerNamespace('appAuthProvider')
|
||||
|
||||
registry.register('settings', new AccountSettingsType(context))
|
||||
registry.register('settings', new PasswordSettingsType(context))
|
||||
registry.register('settings', new EmailNotificationsSettingsType(context))
|
||||
|
@ -142,10 +148,7 @@ export default (context, inject) => {
|
|||
store.registerModule('undoRedo', undoRedoStore)
|
||||
store.registerModule('integration', integrationStore)
|
||||
store.registerModule('userSource', userSourceStore)
|
||||
|
||||
registry.registerNamespace('integration')
|
||||
registry.registerNamespace('service')
|
||||
registry.registerNamespace('userSource')
|
||||
store.registerModule('appAuthProvider', appAuthProviderStore)
|
||||
store.registerModule('notification', notificationStore)
|
||||
|
||||
registry.register('authProvider', new PasswordAuthProviderType(context))
|
||||
|
|
24
web-frontend/modules/core/services/appAuthProvider.js
Normal file
24
web-frontend/modules/core/services/appAuthProvider.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
export default (client) => {
|
||||
return {
|
||||
fetchAll(userSourceId) {
|
||||
return client.get(`user_source/${userSourceId}/app_auth_providers/`)
|
||||
},
|
||||
create(userSourceId, appAuthProviderType, values) {
|
||||
const payload = {
|
||||
type: appAuthProviderType,
|
||||
...values,
|
||||
}
|
||||
|
||||
return client.post(
|
||||
`user_source/${userSourceId}/app_auth_providers/`,
|
||||
payload
|
||||
)
|
||||
},
|
||||
update(appAuthProviderId, values) {
|
||||
return client.patch(`app_auth_provider/${appAuthProviderId}/`, values)
|
||||
},
|
||||
delete(appAuthProviderId) {
|
||||
return client.delete(`app_auth_provider/${appAuthProviderId}/`)
|
||||
},
|
||||
}
|
||||
}
|
198
web-frontend/modules/core/store/appAuthProvider.js
Normal file
198
web-frontend/modules/core/store/appAuthProvider.js
Normal file
|
@ -0,0 +1,198 @@
|
|||
import AppAuthProviderService from '@baserow/modules/core/services/appAuthProvider'
|
||||
|
||||
const state = {}
|
||||
|
||||
const updateContext = {
|
||||
updateTimeout: null,
|
||||
promiseResolve: null,
|
||||
lastUpdatedValues: null,
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
ADD_ITEM(state, { userSource, appAuthProvider, beforeId = null }) {
|
||||
if (beforeId === null) {
|
||||
userSource.appAuthProviders.push(appAuthProvider)
|
||||
} else {
|
||||
const insertionIndex = userSource.appAuthProviders.findIndex(
|
||||
(e) => e.id === beforeId
|
||||
)
|
||||
userSource.appAuthProviders.splice(insertionIndex, 0, appAuthProvider)
|
||||
}
|
||||
},
|
||||
UPDATE_ITEM(
|
||||
state,
|
||||
{ userSource, appAuthProvider: appAuthProviderToUpdate, values }
|
||||
) {
|
||||
userSource.appAuthProviders.forEach((appAuthProvider) => {
|
||||
if (appAuthProvider.id === appAuthProviderToUpdate.id) {
|
||||
Object.assign(appAuthProvider, values)
|
||||
}
|
||||
})
|
||||
},
|
||||
DELETE_ITEM(state, { userSource, appAuthProviderId }) {
|
||||
const index = userSource.appAuthProviders.findIndex(
|
||||
(appAuthProvider) => appAuthProvider.id === appAuthProviderId
|
||||
)
|
||||
if (index > -1) {
|
||||
userSource.appAuthProviders.splice(index, 1)
|
||||
}
|
||||
},
|
||||
CLEAR_ITEMS(state, { userSource }) {
|
||||
userSource.appAuthProviders = []
|
||||
},
|
||||
}
|
||||
|
||||
const actions = {
|
||||
forceCreate({ commit }, { userSource, appAuthProvider, beforeId = null }) {
|
||||
commit('ADD_ITEM', { userSource, appAuthProvider, beforeId })
|
||||
},
|
||||
forceUpdate({ commit }, { userSource, appAuthProvider, values }) {
|
||||
commit('UPDATE_ITEM', { userSource, appAuthProvider, values })
|
||||
},
|
||||
forceDelete({ commit, getters }, { userSource, appAuthProviderId }) {
|
||||
commit('DELETE_ITEM', { userSource, appAuthProviderId })
|
||||
},
|
||||
async create({ dispatch }, { userSource, appAuthProviderType, values }) {
|
||||
const { data: appAuthProvider } = await AppAuthProviderService(
|
||||
this.$client
|
||||
).create(userSource.id, appAuthProviderType, values)
|
||||
|
||||
await dispatch('forceCreate', { userSource, appAuthProvider })
|
||||
|
||||
return appAuthProvider
|
||||
},
|
||||
async update(
|
||||
{ dispatch, getters },
|
||||
{ userSource, appAuthProviderId, values }
|
||||
) {
|
||||
const appAuthProvidersOfUserSource = getters.getUserSources(userSource)
|
||||
const appAuthProvider = appAuthProvidersOfUserSource.find(
|
||||
({ id }) => id === appAuthProviderId
|
||||
)
|
||||
const oldValues = {}
|
||||
const newValues = {}
|
||||
Object.keys(values).forEach((name) => {
|
||||
if (Object.prototype.hasOwnProperty.call(appAuthProvider, name)) {
|
||||
oldValues[name] = appAuthProvider[name]
|
||||
newValues[name] = values[name]
|
||||
}
|
||||
})
|
||||
|
||||
await dispatch('forceUpdate', {
|
||||
userSource,
|
||||
appAuthProvider,
|
||||
values: newValues,
|
||||
})
|
||||
|
||||
try {
|
||||
await AppAuthProviderService(this.$client).update(
|
||||
appAuthProvider.id,
|
||||
values
|
||||
)
|
||||
} catch (error) {
|
||||
await dispatch('forceUpdate', {
|
||||
userSource,
|
||||
appAuthProvider,
|
||||
values: oldValues,
|
||||
})
|
||||
throw error
|
||||
}
|
||||
},
|
||||
|
||||
async debouncedUpdate(
|
||||
{ dispatch, getters },
|
||||
{ userSource, appAuthProviderId, values }
|
||||
) {
|
||||
const appAuthProvider = getters.getAppAuthProviders.find(
|
||||
({ id }) => id === appAuthProviderId
|
||||
)
|
||||
const oldValues = {}
|
||||
const newValues = {}
|
||||
Object.keys(values).forEach((name) => {
|
||||
if (Object.prototype.hasOwnProperty.call(appAuthProvider, name)) {
|
||||
oldValues[name] = appAuthProvider[name]
|
||||
newValues[name] = values[name]
|
||||
}
|
||||
})
|
||||
|
||||
await dispatch('forceUpdate', {
|
||||
userSource,
|
||||
appAuthProvider,
|
||||
values: newValues,
|
||||
})
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const fire = async () => {
|
||||
try {
|
||||
await AppAuthProviderService(this.$client).update(
|
||||
appAuthProvider.id,
|
||||
values
|
||||
)
|
||||
updateContext.lastUpdatedValues = values
|
||||
resolve()
|
||||
} catch (error) {
|
||||
// Revert to old values on error
|
||||
await dispatch('forceUpdate', {
|
||||
userSource,
|
||||
appAuthProvider,
|
||||
values: updateContext.lastUpdatedValues,
|
||||
})
|
||||
reject(error)
|
||||
}
|
||||
}
|
||||
|
||||
if (updateContext.promiseResolve) {
|
||||
updateContext.promiseResolve()
|
||||
updateContext.promiseResolve = null
|
||||
}
|
||||
|
||||
clearTimeout(updateContext.updateTimeout)
|
||||
|
||||
if (!updateContext.lastUpdatedValues) {
|
||||
updateContext.lastUpdatedValues = oldValues
|
||||
}
|
||||
|
||||
updateContext.updateTimeout = setTimeout(fire, 500)
|
||||
updateContext.promiseResolve = resolve
|
||||
})
|
||||
},
|
||||
async delete({ dispatch, getters }, { userSource, appAuthProviderId }) {
|
||||
const appAuthProvidersOfUserSource = getters.getUserSources(userSource)
|
||||
const appAuthProviderIndex = appAuthProvidersOfUserSource.findIndex(
|
||||
(appAuthProvider) => appAuthProvider.id === appAuthProviderId
|
||||
)
|
||||
const appAuthProviderToDelete =
|
||||
appAuthProvidersOfUserSource[appAuthProviderIndex]
|
||||
const beforeId =
|
||||
appAuthProviderIndex !== appAuthProvidersOfUserSource.length - 1
|
||||
? appAuthProvidersOfUserSource[appAuthProviderIndex + 1].id
|
||||
: null
|
||||
|
||||
await dispatch('forceDelete', { userSource, appAuthProviderId })
|
||||
|
||||
try {
|
||||
await AppAuthProviderService(this.$client).delete(appAuthProviderId)
|
||||
} catch (error) {
|
||||
await dispatch('forceCreate', {
|
||||
userSource,
|
||||
appAuthProvider: appAuthProviderToDelete,
|
||||
beforeId,
|
||||
})
|
||||
throw error
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
const getters = {
|
||||
getAppAuthProviders: (state) => (userSource) => {
|
||||
return userSource.appAuthProviders
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations,
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import UserSourceService from '@baserow/modules/core/services/userSource'
|
||||
import _ from 'lodash'
|
||||
|
||||
const state = {
|
||||
// The loaded userSources
|
||||
|
@ -90,10 +91,12 @@ const actions = {
|
|||
async update({ dispatch, getters }, { userSourceId, values }) {
|
||||
const userSourcesOfPage = getters.getUserSources
|
||||
const userSource = userSourcesOfPage.find(({ id }) => id === userSourceId)
|
||||
|
||||
const oldValues = {}
|
||||
const newValues = {}
|
||||
|
||||
Object.keys(values).forEach((name) => {
|
||||
if (Object.prototype.hasOwnProperty.call(userSource, name)) {
|
||||
if (!_.isEqual(userSource[name], values[name])) {
|
||||
oldValues[name] = userSource[name]
|
||||
newValues[name] = values[name]
|
||||
}
|
||||
|
@ -102,7 +105,10 @@ const actions = {
|
|||
await dispatch('forceUpdate', { userSource, values: newValues })
|
||||
|
||||
try {
|
||||
await UserSourceService(this.$client).update(userSource.id, values)
|
||||
const { data: newUserSource } = await UserSourceService(
|
||||
this.$client
|
||||
).update(userSource.id, newValues)
|
||||
await dispatch('forceUpdate', { userSource, values: newUserSource })
|
||||
} catch (error) {
|
||||
await dispatch('forceUpdate', { userSource, values: oldValues })
|
||||
throw error
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
:title="values.authorized_user.first_name"
|
||||
:subtitle="values.authorized_user.username"
|
||||
:initials="values.authorized_user.first_name | nameAbbreviation"
|
||||
avatar-color="primary"
|
||||
avatar-color="blue"
|
||||
/>
|
||||
<div>{{ $t('localBaserowForm.userMessage') }}</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue