Add Windmill workflows and Git auto-sync
- Add wmill.yaml configuration with includes for f/**, u/**, g/** - Add sync_to_git.sh script for automatic Git synchronization - Add initial workflows synced from Windmill: - Test script: u/antigravity/test_git_sync - Admin scripts: u/admin/hub_sync - Setup app: g/all/setup_app - Folders: f/app_custom, f/app_groups, f/app_themes
This commit is contained in:
828
workflows/g/all/setup_app__app/app.yaml
Normal file
828
workflows/g/all/setup_app__app/app.yaml
Normal file
@@ -0,0 +1,828 @@
|
||||
summary: New User Setup App
|
||||
value:
|
||||
css:
|
||||
buttoncomponent:
|
||||
button:
|
||||
class: ''
|
||||
style: ''
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
containercomponent:
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
htmlcomponent:
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
imagecomponent:
|
||||
image:
|
||||
class: ''
|
||||
style: ''
|
||||
schemaformcomponent:
|
||||
description:
|
||||
class: ''
|
||||
style: ''
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
label:
|
||||
class: ''
|
||||
style: ''
|
||||
textcomponent:
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
text:
|
||||
class: ''
|
||||
style: ''
|
||||
textinputcomponent:
|
||||
input:
|
||||
class: ''
|
||||
style: ''
|
||||
fullscreen: false
|
||||
grid:
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 2
|
||||
w: 11
|
||||
x: 0
|
||||
'y': 1
|
||||
'3':
|
||||
fixed: false
|
||||
h: 2
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 0
|
||||
id: a
|
||||
data:
|
||||
id: a
|
||||
type: textcomponent
|
||||
componentInput:
|
||||
type: templatev2
|
||||
value: 'Hello ${ctx.username}'
|
||||
connections: []
|
||||
eval: Setup your Windmill Instance
|
||||
fieldType: template
|
||||
configuration:
|
||||
copyButton:
|
||||
type: static
|
||||
value: false
|
||||
style:
|
||||
type: static
|
||||
value: Body
|
||||
tooltip:
|
||||
type: static
|
||||
value: ''
|
||||
customCss:
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
text:
|
||||
class: text-3xl font-semibold
|
||||
style: ''
|
||||
horizontalAlignment: left
|
||||
verticalAlignment: center
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 2
|
||||
w: 1
|
||||
x: 11
|
||||
'y': 1
|
||||
'3':
|
||||
fixed: false
|
||||
h: 3
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 2
|
||||
id: b
|
||||
data:
|
||||
id: b
|
||||
type: imagecomponent
|
||||
configuration:
|
||||
altText:
|
||||
type: static
|
||||
value: ''
|
||||
imageFit:
|
||||
type: static
|
||||
value: contain
|
||||
source:
|
||||
type: static
|
||||
value: /logo.svg
|
||||
sourceKind:
|
||||
type: static
|
||||
value: url
|
||||
customCss:
|
||||
image:
|
||||
class: ''
|
||||
style: ''
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 12
|
||||
w: 6
|
||||
x: 0
|
||||
'y': 6
|
||||
'3':
|
||||
fixed: false
|
||||
h: 11
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 6
|
||||
id: d
|
||||
data:
|
||||
id: d
|
||||
type: containercomponent
|
||||
configuration: {}
|
||||
customCss:
|
||||
container:
|
||||
class: shadow-lg rounded-lg border p-2 mr-2
|
||||
style: ''
|
||||
numberOfSubgrids: 1
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 12
|
||||
w: 6
|
||||
x: 6
|
||||
'y': 6
|
||||
'3':
|
||||
fixed: false
|
||||
h: 9
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 17
|
||||
id: f
|
||||
data:
|
||||
id: f
|
||||
type: containercomponent
|
||||
configuration: {}
|
||||
customCss:
|
||||
container:
|
||||
class: shadow-lg rounded-lg border p-2 ml-2
|
||||
style: ''
|
||||
numberOfSubgrids: 1
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 2
|
||||
w: 9
|
||||
x: 3
|
||||
'y': 19
|
||||
'3':
|
||||
fixed: false
|
||||
h: 2
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 26
|
||||
id: i
|
||||
data:
|
||||
id: i
|
||||
type: buttoncomponent
|
||||
componentInput:
|
||||
type: runnable
|
||||
autoRefresh: false
|
||||
fields:
|
||||
enable_hub_sync:
|
||||
type: evalv2
|
||||
value: null
|
||||
connections:
|
||||
- id: result
|
||||
componentId: h
|
||||
expr: h.result
|
||||
fieldType: boolean
|
||||
newEmail:
|
||||
type: evalv2
|
||||
value: null
|
||||
connections:
|
||||
- id: values
|
||||
componentId: c
|
||||
expr: c.values.new_email
|
||||
fieldType: string
|
||||
newPassword:
|
||||
type: evalv2
|
||||
value: null
|
||||
connections:
|
||||
- id: values
|
||||
componentId: c
|
||||
expr: c.values.password
|
||||
fieldType: string
|
||||
oldEmail:
|
||||
type: evalv2
|
||||
value: null
|
||||
connections:
|
||||
- id: email
|
||||
componentId: ctx
|
||||
expr: ctx.email
|
||||
fieldType: string
|
||||
sync_now:
|
||||
type: evalv2
|
||||
value: null
|
||||
connections:
|
||||
- id: result
|
||||
componentId: k
|
||||
expr: k.result
|
||||
fieldType: boolean
|
||||
fieldType: any
|
||||
recomputeOnInputChanged: false
|
||||
runnable:
|
||||
name: Change Account
|
||||
inlineScript:
|
||||
content: '!inline change_account.deno.ts'
|
||||
language: deno
|
||||
path: g/all/setup_app/Change_Account
|
||||
schema:
|
||||
$schema: 'https://json-schema.org/draft/2020-12/schema'
|
||||
type: object
|
||||
properties:
|
||||
enable_hub_sync:
|
||||
type: boolean
|
||||
description: ''
|
||||
default: null
|
||||
newEmail:
|
||||
type: string
|
||||
description: ''
|
||||
default: null
|
||||
newPassword:
|
||||
type: string
|
||||
description: ''
|
||||
default: null
|
||||
oldEmail:
|
||||
type: string
|
||||
description: ''
|
||||
default: null
|
||||
sync_now:
|
||||
type: boolean
|
||||
description: ''
|
||||
default: null
|
||||
required:
|
||||
- oldEmail
|
||||
- newEmail
|
||||
- newPassword
|
||||
- enable_hub_sync
|
||||
- sync_now
|
||||
configuration:
|
||||
afterIcon:
|
||||
type: static
|
||||
value: Zap
|
||||
beforeIcon:
|
||||
type: static
|
||||
value: ''
|
||||
color:
|
||||
type: static
|
||||
value: dark
|
||||
disabled:
|
||||
type: evalv2
|
||||
value: false
|
||||
connections:
|
||||
- id: values
|
||||
componentId: c
|
||||
- id: valid
|
||||
componentId: c
|
||||
expr: >-
|
||||
c?.values?.new_email === '' || c?.values?.password === ''||c.valid
|
||||
=== false
|
||||
fillContainer:
|
||||
type: static
|
||||
value: false
|
||||
label:
|
||||
type: static
|
||||
value: Set admin account and hub sync
|
||||
onError:
|
||||
type: oneOf
|
||||
configuration:
|
||||
close:
|
||||
id:
|
||||
type: static
|
||||
value: ''
|
||||
errorOverlay: {}
|
||||
gotoUrl:
|
||||
newTab:
|
||||
type: static
|
||||
value: true
|
||||
url:
|
||||
type: static
|
||||
value: ''
|
||||
open:
|
||||
id:
|
||||
type: static
|
||||
value: ''
|
||||
sendErrorToast:
|
||||
appendError:
|
||||
type: static
|
||||
value: true
|
||||
message:
|
||||
type: static
|
||||
value: ''
|
||||
setTab:
|
||||
setTab:
|
||||
type: static
|
||||
value:
|
||||
- id: p
|
||||
index: 0
|
||||
selected: setTab
|
||||
onSuccess:
|
||||
type: oneOf
|
||||
configuration:
|
||||
clearFiles:
|
||||
id:
|
||||
type: static
|
||||
value: ''
|
||||
close:
|
||||
id:
|
||||
type: static
|
||||
value: ''
|
||||
closeModal:
|
||||
modalId:
|
||||
type: static
|
||||
value: ''
|
||||
gotoUrl:
|
||||
newTab:
|
||||
type: static
|
||||
value: false
|
||||
url:
|
||||
type: evalv2
|
||||
value: ''
|
||||
connections:
|
||||
- id: result
|
||||
componentId: bg_1
|
||||
expr: bg_1.result
|
||||
none: {}
|
||||
open:
|
||||
id:
|
||||
type: static
|
||||
value: ''
|
||||
openModal:
|
||||
modalId:
|
||||
type: static
|
||||
value: ''
|
||||
sendToast:
|
||||
message:
|
||||
type: static
|
||||
value: ''
|
||||
setTab:
|
||||
setTab:
|
||||
type: static
|
||||
value:
|
||||
- id: p
|
||||
index: 1
|
||||
selected: gotoUrl
|
||||
size:
|
||||
type: static
|
||||
value: lg
|
||||
triggerOnAppLoad:
|
||||
type: static
|
||||
value: false
|
||||
customCss:
|
||||
button:
|
||||
class: ''
|
||||
style: ''
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
horizontalAlignment: right
|
||||
recomputeIds: []
|
||||
verticalAlignment: center
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 7
|
||||
w: 12
|
||||
x: 0
|
||||
'y': 21
|
||||
'3':
|
||||
fixed: false
|
||||
h: 8
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 28
|
||||
id: p
|
||||
data:
|
||||
id: p
|
||||
type: conditionalwrapper
|
||||
conditions:
|
||||
- type: evalv2
|
||||
connections:
|
||||
- id: result
|
||||
componentId: i
|
||||
expr: i?.result.error
|
||||
fieldType: boolean
|
||||
- type: evalv2
|
||||
connections: []
|
||||
expr: 'true'
|
||||
fieldType: boolean
|
||||
configuration: {}
|
||||
customCss:
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
numberOfSubgrids: 2
|
||||
hiddenInlineScripts:
|
||||
- type: runnableByName
|
||||
name: Background Runnable 0
|
||||
fields: {}
|
||||
hidden: true
|
||||
- name: Compute URL
|
||||
autoRefresh: true
|
||||
fields: {}
|
||||
inlineScript:
|
||||
content: '!inline compute_url.frontend.js'
|
||||
language: frontend
|
||||
path: u/faton/captivating_app/Compute_URL
|
||||
refreshOn:
|
||||
- id: c
|
||||
key: values
|
||||
suggestedRefreshOn: []
|
||||
recomputeIds: []
|
||||
recomputeOnInputChanged: true
|
||||
norefreshbar: true
|
||||
subgrids:
|
||||
d-0:
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 1
|
||||
w: 12
|
||||
x: 0
|
||||
'y': 0
|
||||
'3':
|
||||
fixed: false
|
||||
h: 1
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 0
|
||||
id: e
|
||||
data:
|
||||
id: e
|
||||
type: textcomponent
|
||||
componentInput:
|
||||
type: templatev2
|
||||
value: 'Hello ${ctx.username}'
|
||||
connections: []
|
||||
eval: Setup a secure account
|
||||
fieldType: template
|
||||
configuration:
|
||||
copyButton:
|
||||
type: static
|
||||
value: false
|
||||
style:
|
||||
type: static
|
||||
value: Body
|
||||
tooltip:
|
||||
type: static
|
||||
value: ''
|
||||
customCss:
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
text:
|
||||
class: text-xl font-semibold px-2
|
||||
style: ''
|
||||
horizontalAlignment: left
|
||||
verticalAlignment: center
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 5
|
||||
w: 12
|
||||
x: 0
|
||||
'y': 2
|
||||
'3':
|
||||
fixed: false
|
||||
h: 5
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 2
|
||||
id: c
|
||||
data:
|
||||
id: c
|
||||
type: schemaformcomponent
|
||||
componentInput:
|
||||
type: static
|
||||
value:
|
||||
order:
|
||||
- new_email
|
||||
- password
|
||||
properties:
|
||||
new_email:
|
||||
type: string
|
||||
description: ''
|
||||
default: ''
|
||||
format: email
|
||||
pattern: '^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$'
|
||||
password:
|
||||
type: string
|
||||
description: ''
|
||||
customErrorMessage: Must have at least 2 chars
|
||||
default: ''
|
||||
password: true
|
||||
pattern: ^..+$
|
||||
required: []
|
||||
fieldType: schema
|
||||
configuration:
|
||||
defaultValues:
|
||||
type: static
|
||||
value: {}
|
||||
displayType:
|
||||
type: static
|
||||
value: false
|
||||
dynamicEnums:
|
||||
type: static
|
||||
value: {}
|
||||
largeGap:
|
||||
type: static
|
||||
value: false
|
||||
customCss:
|
||||
description:
|
||||
class: ''
|
||||
style: ''
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
label:
|
||||
class: ''
|
||||
style: ''
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 1
|
||||
w: 12
|
||||
x: 0
|
||||
'y': 10
|
||||
'3':
|
||||
fixed: false
|
||||
h: 1
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 9
|
||||
id: l
|
||||
data:
|
||||
id: l
|
||||
type: textcomponent
|
||||
componentInput:
|
||||
type: templatev2
|
||||
value: 'Hello ${ctx.username}'
|
||||
connections:
|
||||
- id: email
|
||||
componentId: ctx
|
||||
eval: 'Current email: ${ctx.email}'
|
||||
fieldType: template
|
||||
configuration:
|
||||
copyButton:
|
||||
type: static
|
||||
value: false
|
||||
style:
|
||||
type: static
|
||||
value: Caption
|
||||
tooltip:
|
||||
type: static
|
||||
value: ''
|
||||
customCss:
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
text:
|
||||
class: px-2
|
||||
style: ''
|
||||
horizontalAlignment: left
|
||||
verticalAlignment: top
|
||||
f-0:
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 1
|
||||
w: 12
|
||||
x: 0
|
||||
'y': 0
|
||||
'3':
|
||||
fixed: false
|
||||
h: 1
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 0
|
||||
id: g
|
||||
data:
|
||||
id: g
|
||||
type: textcomponent
|
||||
componentInput:
|
||||
type: templatev2
|
||||
value: 'Hello ${ctx.username}'
|
||||
connections: []
|
||||
eval: Hub Sync
|
||||
fieldType: template
|
||||
configuration:
|
||||
copyButton:
|
||||
type: static
|
||||
value: false
|
||||
style:
|
||||
type: static
|
||||
value: Body
|
||||
tooltip:
|
||||
type: static
|
||||
value: ''
|
||||
customCss:
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
text:
|
||||
class: text-xl font-semibold px-2
|
||||
style: ''
|
||||
horizontalAlignment: left
|
||||
verticalAlignment: center
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 6
|
||||
w: 12
|
||||
x: 0
|
||||
'y': 2
|
||||
'3':
|
||||
fixed: false
|
||||
h: 3
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 2
|
||||
id: m
|
||||
data:
|
||||
id: m
|
||||
type: containercomponent
|
||||
configuration: {}
|
||||
customCss:
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
numberOfSubgrids: 1
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 1
|
||||
w: 12
|
||||
x: 0
|
||||
'y': 10
|
||||
'3':
|
||||
fixed: false
|
||||
h: 2
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 6
|
||||
id: 'n'
|
||||
data:
|
||||
id: 'n'
|
||||
type: textcomponent
|
||||
componentInput:
|
||||
type: templatev2
|
||||
value: 'Hello ${ctx.username}'
|
||||
connections: []
|
||||
eval: The schedule synchronizes resource types from the Hub every day.
|
||||
fieldType: template
|
||||
configuration:
|
||||
copyButton:
|
||||
type: static
|
||||
value: false
|
||||
style:
|
||||
type: static
|
||||
value: Caption
|
||||
tooltip:
|
||||
type: static
|
||||
value: ''
|
||||
customCss:
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
text:
|
||||
class: px-2 xs
|
||||
style: ''
|
||||
horizontalAlignment: left
|
||||
verticalAlignment: top
|
||||
m-0:
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 2
|
||||
w: 12
|
||||
x: 0
|
||||
'y': 0
|
||||
'3':
|
||||
fixed: false
|
||||
h: 1
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 0
|
||||
id: k
|
||||
data:
|
||||
id: k
|
||||
type: checkboxcomponent
|
||||
configuration:
|
||||
defaultValue:
|
||||
type: static
|
||||
value: true
|
||||
disabled:
|
||||
type: static
|
||||
value: false
|
||||
label:
|
||||
type: static
|
||||
value: Sync resource types now
|
||||
customCss:
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
text:
|
||||
class: ''
|
||||
style: ''
|
||||
horizontalAlignment: left
|
||||
recomputeIds: []
|
||||
verticalAlignment: center
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 2
|
||||
w: 12
|
||||
x: 0
|
||||
'y': 2
|
||||
'3':
|
||||
fixed: false
|
||||
h: 1
|
||||
w: 3
|
||||
x: 0
|
||||
'y': 1
|
||||
id: h
|
||||
data:
|
||||
id: h
|
||||
type: checkboxcomponent
|
||||
configuration:
|
||||
defaultValue:
|
||||
type: static
|
||||
value: true
|
||||
disabled:
|
||||
type: static
|
||||
value: false
|
||||
label:
|
||||
type: static
|
||||
value: Sync resource types every day
|
||||
customCss:
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
text:
|
||||
class: ''
|
||||
style: ''
|
||||
horizontalAlignment: left
|
||||
recomputeIds: []
|
||||
verticalAlignment: center
|
||||
p-0:
|
||||
- '12':
|
||||
fixed: false
|
||||
h: 3
|
||||
w: 12
|
||||
x: 0
|
||||
'y': 0
|
||||
'3':
|
||||
fixed: false
|
||||
h: 1
|
||||
w: 2
|
||||
x: 0
|
||||
'y': 0
|
||||
id: j
|
||||
data:
|
||||
id: j
|
||||
type: alertcomponent
|
||||
configuration:
|
||||
type:
|
||||
type: static
|
||||
value: error
|
||||
description:
|
||||
type: evalv2
|
||||
value: Description
|
||||
connections:
|
||||
- id: result
|
||||
componentId: i
|
||||
expr: i?.result?.error?.message
|
||||
collapsible:
|
||||
type: static
|
||||
value: false
|
||||
initiallyCollapsed:
|
||||
type: static
|
||||
value: false
|
||||
notRounded:
|
||||
type: static
|
||||
value: false
|
||||
size:
|
||||
type: static
|
||||
value: sm
|
||||
title:
|
||||
type: static
|
||||
value: 'There were an error with your setup:'
|
||||
tooltip:
|
||||
type: static
|
||||
value: ''
|
||||
customCss:
|
||||
description:
|
||||
class: ''
|
||||
style: ''
|
||||
background:
|
||||
class: ''
|
||||
style: ''
|
||||
container:
|
||||
class: ''
|
||||
style: ''
|
||||
icon:
|
||||
class: ''
|
||||
style: ''
|
||||
title:
|
||||
class: ''
|
||||
style: ''
|
||||
verticalAlignment: center
|
||||
p-1: []
|
||||
theme:
|
||||
type: path
|
||||
path: f/app_themes/theme_0
|
||||
unusedInlineScripts: []
|
||||
72
workflows/g/all/setup_app__app/change_account.deno.ts
Normal file
72
workflows/g/all/setup_app__app/change_account.deno.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import * as wmill from "https://deno.land/x/windmill@v1.99.0/mod.ts";
|
||||
|
||||
export async function main(
|
||||
oldEmail: string,
|
||||
newEmail: string,
|
||||
newPassword: string,
|
||||
enable_hub_sync: boolean,
|
||||
sync_now: boolean,
|
||||
) {
|
||||
try {
|
||||
await wmill.UserService.createUserGlobally({
|
||||
requestBody: {
|
||||
email: newEmail,
|
||||
password: newPassword,
|
||||
super_admin: true,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
throw Error("User already exists: " + e.body);
|
||||
}
|
||||
|
||||
let new_token;
|
||||
|
||||
try {
|
||||
new_token = await wmill.UserService.login({
|
||||
requestBody: {
|
||||
email: newEmail,
|
||||
password: newPassword,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
throw Error("Login failed: " + e.body);
|
||||
}
|
||||
|
||||
wmill.setClient(new_token, Deno.env.get("BASE_INTERNAL_URL")!);
|
||||
|
||||
if (sync_now) {
|
||||
try {
|
||||
await wmill.JobService.runScriptByPath({
|
||||
workspace: "admins",
|
||||
path: "u/admin/hub_sync",
|
||||
requestBody: {},
|
||||
});
|
||||
} catch (e) {
|
||||
throw Error("Hub sync failed:" + e.body);
|
||||
}
|
||||
}
|
||||
|
||||
if (enable_hub_sync) {
|
||||
try {
|
||||
await wmill.ScheduleService.createSchedule({
|
||||
workspace: "admins",
|
||||
requestBody: {
|
||||
path: "g/all/hub_sync",
|
||||
schedule: "0 0 0 * * *",
|
||||
script_path: "u/admin/hub_sync",
|
||||
is_flow: false,
|
||||
args: {},
|
||||
enabled: true,
|
||||
timezone: "Etc/UTC",
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
throw Error("Error creating schedule: " + e.body);
|
||||
}
|
||||
}
|
||||
try {
|
||||
await wmill.UserService.globalUserDelete({ email: oldEmail });
|
||||
} catch (e) {
|
||||
throw Error("Deleting old account failed: " + e.body);
|
||||
}
|
||||
}
|
||||
1
workflows/g/all/setup_app__app/compute_url.frontend.js
Normal file
1
workflows/g/all/setup_app__app/compute_url.frontend.js
Normal file
@@ -0,0 +1 @@
|
||||
return '/user/logout?rd=' + encodeURIComponent('/user/login?email=' + c.values.new_email)
|
||||
Reference in New Issue
Block a user