mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 10:10:57 +00:00
add permanent purge functionality for wagons and routes
- Implemented a method in to permanently delete wagons without history. - Added corresponding permissions for hard delete actions in . - Updated the UI components to include purge actions, ensuring they are only available to users with the appropriate permissions. - Created modals for confirming permanent deletions in and . - Enhanced API services to handle purge requests for locomotives, wagons, and routes. - Added tests for the purge functionality in both and services to ensure proper behavior and error handling.
This commit is contained in:
@@ -3,7 +3,10 @@ import Handlebars from 'handlebars';
|
||||
/** One numbered clause of a dynamic article, with optional nested bullets. */
|
||||
export interface RenderedClause {
|
||||
text: string;
|
||||
/** Computed outline number, e.g. "3" or "2.1.4". */
|
||||
/**
|
||||
* Computed outline marker for this clause at its own level: "3" at depth 1,
|
||||
* "b" at depth 2, "iv" at depth 3, cycling back to arabic at depth 4.
|
||||
*/
|
||||
number: string;
|
||||
/** Nesting level: 1 = clause, 2 = sub-clause (x.y), 3 = x.y.z, … */
|
||||
depth: number;
|
||||
@@ -35,6 +38,51 @@ const CLAUSE_NUMBER_RE = /^(?:(\d+(?:\.\d+)+)[.)]?|(\d+)[.)])(?:\s+|$)/;
|
||||
/** Deepest supported sub-clause level (1.1.1.1.1.1). */
|
||||
const MAX_CLAUSE_DEPTH = 6;
|
||||
|
||||
/** 1 → "a", 2 → "b", … 27 → "aa". */
|
||||
function toAlpha(n: number): string {
|
||||
let out = '';
|
||||
let value = n;
|
||||
while (value > 0) {
|
||||
const rem = (value - 1) % 26;
|
||||
out = String.fromCharCode(97 + rem) + out;
|
||||
value = Math.floor((value - 1) / 26);
|
||||
}
|
||||
return out || 'a';
|
||||
}
|
||||
|
||||
const ROMAN: Array<[number, string]> = [
|
||||
[1000, 'm'], [900, 'cm'], [500, 'd'], [400, 'cd'],
|
||||
[100, 'c'], [90, 'xc'], [50, 'l'], [40, 'xl'],
|
||||
[10, 'x'], [9, 'ix'], [5, 'v'], [4, 'iv'], [1, 'i'],
|
||||
];
|
||||
|
||||
/** 1 → "i", 4 → "iv", 9 → "ix". */
|
||||
function toRoman(n: number): string {
|
||||
let value = n;
|
||||
let out = '';
|
||||
for (const [amount, numeral] of ROMAN) {
|
||||
while (value >= amount) {
|
||||
out += numeral;
|
||||
value -= amount;
|
||||
}
|
||||
}
|
||||
return out || 'i';
|
||||
}
|
||||
|
||||
/**
|
||||
* Word-processor outline markers, cycling by depth the way Quill's own list
|
||||
* rendering does: 1. → a. → i. → 1. … Depth 1 keeps plain arabic numerals so
|
||||
* top-level clauses read as "1.", "2." in the contract; the marker is the
|
||||
* clause's own counter at its level, NOT a dotted path — "a" under clause 2 is
|
||||
* "a", not "2.a".
|
||||
*/
|
||||
export function clauseMarker(counter: number, depth: number): string {
|
||||
const style = (depth - 1) % 3;
|
||||
if (style === 1) return toAlpha(counter);
|
||||
if (style === 2) return toRoman(counter);
|
||||
return String(counter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a template article body into clauses. Format: one clause per line.
|
||||
* A leading outline number ("2. ", "2.1 ", "2.1.3 ") nests the line as a
|
||||
@@ -82,7 +130,7 @@ export function parseArticleBody(body: string): Pick<RenderedArticle, 'paragraph
|
||||
|
||||
clauses.push({
|
||||
text: match ? line.slice(match[0].length).trim() : line,
|
||||
number: counters.slice(0, depth).join('.'),
|
||||
number: clauseMarker(counters[depth - 1], depth),
|
||||
depth,
|
||||
bullets: [],
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user