feat: workspace renaming (#3452)

* feat: workspace renaming

* feat: openapi spec

* chore: sqlx prepare
This commit is contained in:
HugoCasa
2024-03-22 18:54:29 +01:00
committed by GitHub
parent 089aab880d
commit fdc98b73ae
38 changed files with 1131 additions and 9 deletions
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE resource SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "00f68ea1ad2d5ab045b4a20ce3f4dd7850041e396e14890e37e1d0db276d3694"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE usr SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "0659bab15d4cccdb04c7a57e0e3bbb6bfebb8896601a27ddf5618d4eae678bc1"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE audit SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "0ba594244a366a31d9bed97a2d7b031d42c23463599d267d1712d1af1d26b321"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE workspace_key SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "0d0c379b1cd2eec15869dd0b1a31886a95d53096fdcb1cdb1e0eb282b54105dc"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE variable SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "15c29ab03fdeda346adc4db3fd0b9d9aee1a99f0c795afe203efe42b967569a5"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE resource_type SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "2133e06ac9f7de884dbd36d51bca9a427bde64a9e278658bc0777e23abde4cd5"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE usr_to_group SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "26c1c56290d2ef5dae9d19796560c89f99fc4d18a9ea6bc9527563fd38b134b2"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO group_ SELECT $1, name, summary, extra_perms FROM group_ WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "2f998f9044412da6ad785f158ead132f219dd0f96003414d75ccb1953a3827ac"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE app SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "5395887680e4ff458a962d99614085e45a723964b7937cfe9943019e5c49df90"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE draft SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "5422a53e642c491b02be5d17fe9d7389a42a84c21fea9876c84a5ba719b6ede5"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE token SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "543b8f6e4850c15439e9bed8432db071c361867f9603d962b6edec6c18160491"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE folder SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "5876d8271adcb75752d518fc52ac192e162469a504338b4a0a37e8bcec114385"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE job_stats SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "65121a4bfba70c2d7055a2b58c8520fddaef1bd9a3f041e851f9c136c73d34e7"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE completed_job SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "6681048ee83236e9eb33b407b5d3cf89f563e57d5d3e7981d58cecf147b9bf1e"
}
@@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO workspace SELECT $1, $2, owner, deleted, premium, is_overquota FROM workspace WHERE id = $3",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "6d89ac43c4ae3a17167a44c802df72bc506803b79fe93ab3b203fb0690b1bef1"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE account SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "73a2dbe03a7debbcb236765a9f9d73f3aeb11469f773797ece590f9327878085"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE job_logs SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "7e90578bb37b2923cd94c201f1818c8c5b0bd62c9555949dda2e6aba3e09a4f0"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE schedule SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "7fff1cc19a4b2a7ee99b1e4bd74986f4c9253052272145f37c4da1dfe5be0754"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE workspace_settings SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "93e6cdf58803f63d7d465f9d778c052c40dcdacade0f9b9921860160604f3763"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE dependency_map SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "940b6f4869e545cbeb796ef379dd718cf03e3752607b6bf7c85a176f8a44cbc2"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE script SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "96bc4b0f9909bd555fa58547fa87e4b311c4b515b9e3d14d922d7aec53a9505e"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE raw_app SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "a0d7dbff9ef98c3cc25281cb5dc9e29023766ba04c57d07c3f89f07640833619"
}
@@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT name FROM workspace WHERE id = $1",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "name",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false
]
},
"hash": "a31147b85e68f49e635deda0bd5f1401ca297e14bdbfa350dfd9f0f91a7c1f54"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE deployment_metadata SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "b101ce2acb77e2f3861d9e50ea241f55bb3ffc8afd26f377c8f0c9f894321806"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE workspace SET name = $1 WHERE id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "b8959764cd7c67f6535044cfd42ebdbca3aadb5197cf395ba9a1fdee0e55967e"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE capture SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "bf0ae8e884556a87f8a495aa2c8245e69b8f68b7c2748b2b1c29a3f013123a09"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE usage SET id = $1 WHERE id = $2 AND is_workspace = true",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "c3e8866a3e86e26f0225f9590ebad3d209d663ac5db05e187b2789fdf4d67489"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE favorite SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "c721347a78ada56730f92038820e4b7e9e1f541f76bb37a0906a3c96dfe8169e"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE queue SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "cbf5a2b315a7e89689ee86acf452f40fd82605c456aff479890462f4d0202316"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE input SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "cfa0daf8f342aedd2d9b0bbb00965187e3838bbfe6a14be5b7a308e246123f71"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE flow SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "e26e976a64d267557c528ce1bf006b97de9f89e53cb36a3b0ed11e7c18caf55f"
}
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE workspace_invite SET workspace_id = $1 WHERE workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "fc384ad2e85f3b21887d65ae68e8c408acbe4ad5c5c63a9ca9dac35dbb2eec2e"
}
+71
View File
@@ -1184,6 +1184,77 @@ paths:
schema:
type: string
/w/{workspace}/workspaces/get_workspace_name:
get:
summary: get workspace name
operationId: getWorkspaceName
tags:
- workspace
parameters:
- $ref: "#/components/parameters/WorkspaceId"
responses:
"200":
description: status
content:
text/plain:
schema:
type: string
/w/{workspace}/workspaces/change_workspace_name:
post:
summary: change workspace name
operationId: changeWorkspaceName
tags:
- workspace
parameters:
- $ref: "#/components/parameters/WorkspaceId"
requestBody:
content:
application/json:
schema:
type: object
properties:
new_name:
type: string
required:
- username
responses:
"200":
description: status
content:
text/plain:
schema:
type: string
/w/{workspace}/workspaces/change_workspace_id:
post:
summary: change workspace id
operationId: changeWorkspaceId
tags:
- workspace
parameters:
- $ref: "#/components/parameters/WorkspaceId"
requestBody:
content:
application/json:
schema:
type: object
properties:
new_id:
type: string
new_name:
type: string
required:
- username
responses:
"200":
description: status
content:
text/plain:
schema:
type: string
/w/{workspace}/users/whois/{username}:
get:
summary: whois
+374 -1
View File
@@ -108,7 +108,10 @@ pub fn workspaced_service() -> Router {
"/encryption_key",
get(get_encryption_key).post(set_encryption_key),
)
.route("/leave", post(leave_workspace));
.route("/leave", post(leave_workspace))
.route("/get_workspace_name", get(get_workspace_name))
.route("/change_workspace_name", post(change_workspace_name))
.route("/change_workspace_id", post(change_workspace_id));
#[cfg(feature = "stripe")]
{
@@ -2632,3 +2635,373 @@ async fn tarball_workspace(
];
Ok((headers, body))
}
async fn get_workspace_name(
authed: ApiAuthed,
Path(w_id): Path<String>,
Extension(user_db): Extension<UserDB>,
) -> Result<String> {
let mut tx = user_db.begin(&authed).await?;
let workspace = sqlx::query_scalar!("SELECT name FROM workspace WHERE id = $1", &w_id)
.fetch_one(&mut *tx)
.await?;
tx.commit().await?;
Ok(workspace)
}
#[derive(Deserialize)]
struct ChangeWorkspaceName {
new_name: String,
}
async fn change_workspace_name(
authed: ApiAuthed,
Path(w_id): Path<String>,
Extension(db): Extension<DB>,
Json(rw): Json<ChangeWorkspaceName>,
) -> Result<String> {
require_admin(authed.is_admin, &authed.username)?;
let mut tx = db.begin().await?;
sqlx::query!(
"UPDATE workspace SET name = $1 WHERE id = $2",
&rw.new_name,
&w_id
)
.execute(&mut *tx)
.await?;
audit_log(
&mut *tx,
&authed.username,
"workspace.change_workspace_name",
ActionKind::Update,
&w_id,
Some(&authed.email),
None,
)
.await?;
tx.commit().await?;
Ok(format!("updated workspace name to {}", &rw.new_name))
}
#[derive(Deserialize)]
struct ChangeWorkspaceId {
new_id: String,
new_name: String,
}
async fn change_workspace_id(
authed: ApiAuthed,
Path(old_id): Path<String>,
Extension(db): Extension<DB>,
Json(rw): Json<ChangeWorkspaceId>,
) -> Result<String> {
if *CLOUD_HOSTED {
return Err(Error::BadRequest(
"This feature is not available on the cloud".to_string(),
));
}
if *CREATE_WORKSPACE_REQUIRE_SUPERADMIN {
require_super_admin(&db, &authed.email).await?;
} else {
require_admin(authed.is_admin, &authed.username)?;
}
let mut tx = db.begin().await?;
let workspace_conflict = sqlx::query_scalar!(
"SELECT EXISTS(SELECT 1 FROM workspace WHERE id = $1)",
&rw.new_id,
)
.fetch_one(&mut *tx)
.await?
.unwrap_or(false);
if workspace_conflict {
return Err(Error::BadRequest(format!(
"workspace id {} already used",
&rw.new_id
)));
}
// duplicate workspace with new id name
sqlx::query!(
"INSERT INTO workspace SELECT $1, $2, owner, deleted, premium, is_overquota FROM workspace WHERE id = $3",
&rw.new_id,
&rw.new_name,
&old_id
).execute(&mut *tx).await?;
sqlx::query!(
"UPDATE account SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE app SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE audit SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE capture SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE completed_job SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE dependency_map SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE dependency_map SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE deployment_metadata SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE draft SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE favorite SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE flow SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE folder SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
// have to duplicate group_ with new workspace id because of foreign key constraint
sqlx::query!(
"INSERT INTO group_ SELECT $1, name, summary, extra_perms FROM group_ WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE usr_to_group SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
// then delete old group_
sqlx::query!("DELETE FROM group_ WHERE workspace_id = $1", &old_id)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE input SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE job_logs SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE job_stats SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE queue SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE raw_app SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE resource SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE resource_type SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE schedule SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE script SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE token SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE usage SET id = $1 WHERE id = $2 AND is_workspace = true",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE usr SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE variable SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE workspace_invite SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE workspace_key SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
sqlx::query!(
"UPDATE workspace_settings SET workspace_id = $1 WHERE workspace_id = $2",
&rw.new_id,
&old_id
)
.execute(&mut *tx)
.await?;
// delete old workspace
sqlx::query!("DELETE FROM workspace WHERE id = $1", &old_id)
.execute(&mut *tx)
.await?;
audit_log(
&mut *tx,
&authed.username,
"workspace.change_workspace_id",
ActionKind::Update,
&rw.new_id,
Some(&authed.email),
None,
)
.await?;
tx.commit().await?;
Ok(format!(
"updated workspace from {} to {}",
&old_id, &rw.new_id
))
}
@@ -39,6 +39,7 @@
{#if open}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<div
on:click={() => (open = false)}
transition:fadeFast|local
@@ -54,6 +55,7 @@
<div class="fixed inset-0 z-10 overflow-y-auto">
<div class="flex min-h-full items-center justify-center p-4">
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
on:click|stopPropagation
class={twMerge(
@@ -0,0 +1,104 @@
<script lang="ts">
import { workspaceStore } from '$lib/stores'
import Alert from '../common/alert/Alert.svelte'
import Button from '../common/button/Button.svelte'
import { sendUserToast } from '$lib/toast'
import { WorkspaceService } from '$lib/gen'
import Modal from '../common/modal/Modal.svelte'
import { Pen } from 'lucide-svelte'
import { isCloudHosted } from '$lib/cloud'
let newName = ''
let newId = ''
let checking = false
let errorId = ''
$: newId = newName.toLowerCase().replace(/\s/gi, '-')
$: validateName(newId)
async function validateName(id: string): Promise<void> {
checking = true
let exists = await WorkspaceService.existsWorkspace({ requestBody: { id } })
if (exists) {
errorId = 'ID already exists'
} else if (id != '' && !/^\w+(-\w+)*$/.test(id)) {
errorId = 'ID can only contain letters, numbers and dashes and must not finish by a dash'
} else {
errorId = ''
}
checking = false
}
async function renameWorkspace() {
open = false
await WorkspaceService.changeWorkspaceId({
workspace: $workspaceStore!,
requestBody: {
new_name: newName,
new_id: newId
}
})
sendUserToast(`Renamed workspace to ${newName}. Reloading...`)
await new Promise((resolve) => setTimeout(resolve, 1000))
window.location.href = '/workspace_settings?tab=general&workspace=' + newId
}
export let open = false
</script>
<div>
<p class="font-semibold text-sm">Workspace ID</p>
<div class="flex flex-row gap-0.5 items-center">
<p class="text-sm text-secondary">{$workspaceStore ?? ''}</p>
{#if !isCloudHosted()}
<Button
on:click={() => {
open = true
}}
size="xs"
spacingSize="xs2"
color="light"
iconOnly
startIcon={{
icon: Pen
}}
/>
{/if}
</div>
</div>
<Modal bind:open title="Change workspace ID">
<div class="flex flex-col gap-4">
<Alert type="warning" title="Warning">
You will have to update your webhook calls and your CLI sync configuration.
</Alert>
<p class="text-secondary text-sm"
>Current ID <br /> <span class="font-bold">{$workspaceStore ?? ''}</span></p
>
<label class="block">
<span class="text-secondary text-sm">New name</span>
<input type="text" bind:value={newName} />
</label>
<label class="block">
<span class="text-secondary text-sm">New ID</span>
<input type="text" bind:value={newId} />
{#if errorId}
<div class="text-red-500 text-xs mt-1">{errorId}</div>
{/if}
</label>
</div>
<svelte:fragment slot="actions">
<Button
size="sm"
disabled={checking || errorId.length > 0 || !newName || !newId}
on:click={() => {
renameWorkspace()
}}
>
Save
</Button>
</svelte:fragment>
</Modal>
@@ -0,0 +1,78 @@
<script lang="ts">
import { workspaceStore } from '$lib/stores'
import Button from '../common/button/Button.svelte'
import { sendUserToast } from '$lib/toast'
import { WorkspaceService } from '$lib/gen'
import Modal from '../common/modal/Modal.svelte'
import { Pen } from 'lucide-svelte'
let newName = ''
let currentName = ''
async function getWorkspaceName() {
currentName = await WorkspaceService.getWorkspaceName({ workspace: $workspaceStore! })
}
getWorkspaceName()
async function renameWorkspace() {
open = false
await WorkspaceService.changeWorkspaceName({
workspace: $workspaceStore!,
requestBody: {
new_name: newName
}
})
sendUserToast(`Changed workspace name to ${newName}`)
newName = ''
getWorkspaceName()
}
export let open = false
</script>
<div>
<p class="font-semibold text-sm">Workspace name</p>
<div class="flex flex-row gap-0.5 items-center">
<p class="text-sm text-secondary">{currentName}</p>
<Button
on:click={() => {
open = true
}}
size="xs"
spacingSize="xs2"
color="light"
iconOnly
startIcon={{
icon: Pen
}}
/>
</div>
</div>
<Modal bind:open title="Change workspace name">
<div class="flex flex-col gap-4 mt-4">
{#if currentName}
<p class="text-secondary text-sm"
>Current name <br /> <span class="font-bold">{currentName}</span></p
>
{/if}
<label class="block">
<span class="text-secondary text-sm">New name</span>
<input type="text" bind:value={newName} />
</label>
</div>
<svelte:fragment slot="actions">
<Button
size="sm"
disabled={!newName}
on:click={() => {
renameWorkspace()
}}
>
Save
</Button>
</svelte:fragment>
</Modal>
@@ -51,6 +51,8 @@
import TestOpenaiKey from '$lib/components/copilot/TestOpenaiKey.svelte'
import Portal from 'svelte-portal'
import { fade } from 'svelte/transition'
import ChangeWorkspaceName from '$lib/components/settings/ChangeWorkspaceName.svelte'
import ChangeWorkspaceId from '$lib/components/settings/ChangeWorkspaceId.svelte'
type GitSyncTypeMap = {
scripts: boolean
@@ -125,7 +127,7 @@
| 'users'
| 'slack'
| 'premium'
| 'export_delete'
| 'general'
| 'webhook'
| 'deploy_to'
| 'error_handler') ?? 'users'
@@ -685,8 +687,8 @@
<Tab size="xs" value="encryption">
<div class="flex gap-2 items-center my-1"> Encryption </div>
</Tab>
<Tab size="xs" value="export_delete">
<div class="flex gap-2 items-center my-1"> Delete Workspace </div>
<Tab size="xs" value="general">
<div class="flex gap-2 items-center my-1"> General </div>
</Tab>
</Tabs>
</div>
@@ -817,12 +819,16 @@
See more on <a href="https://www.windmill.dev/docs/integrations/slack">documentation</a>.
</div>
</div>
{:else if tab == 'export_delete'}
{:else if tab == 'general'}
<div class="flex flex-col gap-4 my-8">
<div class="flex flex-col gap-1">
<div class=" text-primary text-lg font-semibold">Export or Delete workspace</div>
</div>
<div class=" text-primary text-lg font-semibold">General</div>
</div>
<div class="flex flex-col gap-10">
<ChangeWorkspaceName />
<ChangeWorkspaceId />
</div>
<PageHeader title="Export workspace" primary={false} />
<div class="flex justify-start">
<Button
@@ -876,7 +882,7 @@
goto('/user/workspaces')
}}
>
Delete workspace (superadmin)
General (superadmin)
</Button>
{/if}
</div>