Duplicating a copy names it after the original; a failed duplicate or delete says why
This commit is contained in:
@@ -26,7 +26,13 @@ from pydantic import BaseModel, Field, field_validator, model_validator
|
||||
|
||||
from fluksio.flow.messages import DType, qualify
|
||||
from fluksio.flow.schemas import FlowDef, _validate_name
|
||||
from fluksio.flow.store import FlowStore, StaleVersion, _updated_at, checked
|
||||
from fluksio.flow.store import (
|
||||
FlowStore,
|
||||
StaleVersion,
|
||||
_updated_at,
|
||||
checked,
|
||||
copy_name,
|
||||
)
|
||||
|
||||
#: Sibling of the shared-node library, and likewise not a flow.
|
||||
DASHBOARD_DIR = "_dashboards"
|
||||
@@ -854,10 +860,7 @@ class DashboardStore:
|
||||
"""
|
||||
with self._lock, self.flows._write_lock:
|
||||
source = self.read(name, draft=True)
|
||||
new_name, count = f"{name}_copy", 1
|
||||
while self.exists(new_name):
|
||||
count += 1
|
||||
new_name = f"{name}_copy_{count}"
|
||||
new_name = copy_name(name, self.exists)
|
||||
copy = source.model_copy(
|
||||
update={
|
||||
"name": new_name,
|
||||
|
||||
@@ -16,10 +16,11 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import threading
|
||||
from collections.abc import Iterable
|
||||
from collections.abc import Callable, Iterable
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
|
||||
@@ -134,6 +135,16 @@ def _same_content(left: FlowDef, right: FlowDef) -> bool:
|
||||
)
|
||||
|
||||
|
||||
def copy_name(name: str, taken: Callable[[str], bool]) -> str:
|
||||
"""``{name}_copy``, then ``_copy_2`` and on, from a copy's own original."""
|
||||
base = re.sub(r"_copy(_\d+)?$", "", name)
|
||||
new_name, count = f"{base}_copy", 1
|
||||
while taken(new_name):
|
||||
count += 1
|
||||
new_name = f"{base}_copy_{count}"
|
||||
return new_name
|
||||
|
||||
|
||||
class FlowStore:
|
||||
"""Reads and writes flows, committing every change."""
|
||||
|
||||
@@ -698,12 +709,9 @@ class FlowStore:
|
||||
"""
|
||||
with self._write_lock:
|
||||
source = self.read_flow(name, draft=True)
|
||||
new_name, count = f"{name}_copy", 1
|
||||
# The directory rather than `exists`: anything left in it would
|
||||
# otherwise end up in the copy.
|
||||
while self._flow_dir(new_name).exists():
|
||||
count += 1
|
||||
new_name = f"{name}_copy_{count}"
|
||||
new_name = copy_name(name, lambda n: self._flow_dir(n).exists())
|
||||
|
||||
copy = source.model_copy(
|
||||
update={
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Check, Copy, Plus, Search, Trash2 } from "lucide-react"
|
||||
import { motion } from "motion/react"
|
||||
import { type ReactNode, useRef, useState } from "react"
|
||||
|
||||
import type { ApiError } from "@/client"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
Dialog,
|
||||
@@ -22,6 +23,7 @@ import {
|
||||
} from "@/components/ui/tooltip"
|
||||
import useCustomToast from "@/hooks/useCustomToast"
|
||||
import { transitions } from "@/lib/motion"
|
||||
import { extractErrorMessage } from "@/utils"
|
||||
|
||||
/**
|
||||
* The bar over the flows and dashboards lists: find one, publish what is
|
||||
@@ -233,8 +235,8 @@ function useBatch(
|
||||
for (const name of names) {
|
||||
try {
|
||||
await act(name)
|
||||
} catch {
|
||||
failed.push(name)
|
||||
} catch (err) {
|
||||
failed.push(`${name} (${extractErrorMessage(err as ApiError)})`)
|
||||
}
|
||||
}
|
||||
return failed
|
||||
|
||||
Reference in New Issue
Block a user