diff --git a/.build/jsonSchema.ts b/.build/jsonSchema.ts index 50b9ff097..7a700c1e2 100644 --- a/.build/jsonSchema.ts +++ b/.build/jsonSchema.ts @@ -19,6 +19,7 @@ const MERMAID_CONFIG_DIAGRAM_KEYS = [ 'xyChart', 'requirement', 'mindmap', + 'kanban', 'timeline', 'gitGraph', 'c4', diff --git a/.changeset/kind-drinks-invent.md b/.changeset/kind-drinks-invent.md new file mode 100644 index 000000000..244be2bf6 --- /dev/null +++ b/.changeset/kind-drinks-invent.md @@ -0,0 +1,5 @@ +--- +'mermaid': minor +--- + +Adding Kanban board, a new diagram type diff --git a/.changeset/thick-elephants-search.md b/.changeset/thick-elephants-search.md new file mode 100644 index 000000000..5e29c42d6 --- /dev/null +++ b/.changeset/thick-elephants-search.md @@ -0,0 +1,5 @@ +--- +'mermaid': patch +--- + +fix: error `mermaid.parse` on an invalid shape, so that it matches the errors thrown by `mermaid.render` diff --git a/.cspell/mermaid-terms.txt b/.cspell/mermaid-terms.txt index 8551bd196..cb6db41de 100644 --- a/.cspell/mermaid-terms.txt +++ b/.cspell/mermaid-terms.txt @@ -12,6 +12,7 @@ gantt gitgraph gzipped handDrawn +kanban knsv Knut marginx diff --git a/cypress/integration/rendering/kanban.spec.ts b/cypress/integration/rendering/kanban.spec.ts new file mode 100644 index 000000000..6293776d6 --- /dev/null +++ b/cypress/integration/rendering/kanban.spec.ts @@ -0,0 +1,136 @@ +import { imgSnapshotTest } from '../../helpers/util.ts'; + +describe('Kanban diagram', () => { + it('1: should render a kanban with a single section', () => { + imgSnapshotTest( + `kanban + id1[Todo] + docs[Create Documentation] + docs[Create Blog about the new diagram] + `, + {} + ); + }); + it('2: should render a kanban with multiple sections', () => { + imgSnapshotTest( + `kanban + id1[Todo] + docs[Create Documentation] + id2 + docs[Create Blog about the new diagram] + `, + {} + ); + }); + it('3: should render a kanban with a single wrapping node', () => { + imgSnapshotTest( + `kanban + id1[Todo] + id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char, wrapping] + `, + {} + ); + }); + it('4: should handle the height of a section with a wrapping node at the end', () => { + imgSnapshotTest( + `kanban + id1[Todo] + id2[One line] + id3[Title of diagram is more than 100 chars when user duplicates diagram with 100 char, wrapping] + `, + {} + ); + }); + it('5: should handle the height of a section with a wrapping node at the top', () => { + imgSnapshotTest( + `kanban + id1[Todo] + id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char, wrapping] + id3[One line] + `, + {} + ); + }); + it('6: should handle the height of a section with a wrapping node in the middle', () => { + imgSnapshotTest( + `kanban + id1[Todo] + id2[One line] + id3[Title of diagram is more than 100 chars when user duplicates diagram with 100 char, wrapping] + id4[One line] + `, + {} + ); + }); + it('6: should handle assigments', () => { + imgSnapshotTest( + `kanban + id1[Todo] + docs[Create Documentation] + id2[In progress] + docs[Create Blog about the new diagram]@{ assigned: 'knsv' } + `, + {} + ); + }); + it('7: should handle prioritization', () => { + imgSnapshotTest( + `kanban + id2[In progress] + vh[Very High]@{ priority: 'Very High' } + h[High]@{ priority: 'High' } + m[Default priority] + l[Low]@{ priority: 'Low' } + vl[Very Low]@{ priority: 'Very Low' } + `, + {} + ); + }); + it('7: should handle external tickets', () => { + imgSnapshotTest( + `kanban + id1[Todo] + docs[Create Documentation] + id2[In progress] + docs[Create Blog about the new diagram]@{ ticket: MC-2037 } + `, + {} + ); + }); + it('8: should handle assignments, prioritization and tickets ids in the same item', () => { + imgSnapshotTest( + `kanban + id2[In progress] + docs[Create Blog about the new diagram]@{ priority: 'Very Low', ticket: MC-2037, assigned: 'knsv' } + `, + {} + ); + }); + it('10: Full example', () => { + imgSnapshotTest( + `--- +config: + kanban: + ticketBaseUrl: 'https://abc123.atlassian.net/browse/#TICKET#' +--- +kanban + id1[Todo] + docs[Create Documentation] + docs[Create Blog about the new diagram] + id7[In progress] + id6[Create renderer so that it works in all cases. We also add som extra text here for testing purposes. And some more just for the extra flare.] + id8[Design grammar]@{ assigned: 'knsv' } + id9[Ready for deploy] + id10[Ready for test] + id11[Done] + id5[define getData] + id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char]@{ ticket: MC-2036, priority: 'Very High'} + id3[Update DB function]@{ ticket: MC-2037, assigned: knsv, priority: 'High' } + id4[Create parsing tests]@{ ticket: MC-2038, assigned: 'K.Sveidqvist', priority: 'High' } + id66[last item]@{ priority: 'Very Low', assigned: 'knsv' } + id12[Can't reproduce] + `, + {} + ); + }); +}); diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index d93881018..1de071283 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -34,6 +34,7 @@ /* background: rgb(221, 208, 208); */ /* background: #333; */ font-family: 'Arial'; + /* color: white; */ /* font-size: 18px !important; */ } @@ -83,349 +84,36 @@
-
----
- title: hello2
- config:
- look: handDrawn
- layout: elk
- elk:
-
-
----
-stateDiagram-v2
- direction LR
- accTitle: An idealized Open Source supply-chain graph
-
- %%
- state "🟦 Importer" as author_importer
- state "🟥 Supplier, Owner" as author_owner
- state "🟨🟥 Maintainer, Author\n🟨 Custodian" as author
- state "🟩 Distributor" as repository_distributor
- state "🟦 Importer" as language_importer
- state "🟦🟨 Packager" as language_packager
- state "🟦🟨 OSS Steward" as language_steward
- state "🟨 Curator" as language_curator
- state "🟩 Distributor" as language_distributor
- state "🟦 Contributor" as contributor
- state "🟦 Importer" as package_importer
- state "🟨 Patcher" as package_patcher
- state "🟨🟦 Builder\n🟨🟦 Packager\n🟨🟦 Containerizer" as package_packager
- state "🟨 Curator" as package_curator
- state "🟩 Distributor" as package_distributor
- state "🟦 Importer" as integrator_importer
- state "🟥 Supplier, Manufacturer, Owner" as integrator_owner
- state "🟦🟨🟥 Integrator, Developer" as integrator_developer
- state "🟩🟨 SBOM Redactor\n🟩 Publisher" as integrator_publisher
- state "🟦🟨 Builder" as integrator_builder
- state "🟨 Deployer" as deployer
- state "🟦 Vuln. Checker" as integrator_checker
- state "🟩🟨 SBOM Redactor" as redactor
- state "🟦 Consumer\n🟦 User" as consumer
- state "🟦 Auditor" as auditor_internal
- state "🟦 Auditor" as auditor_external
-
- %%
- classDef createsSBOM stroke:red,stroke-width:3px;
- classDef updatesSBOM stroke:yellow,stroke-width:3px;
- classDef assemblesSBOM stroke:yellow,stroke-width:3px;
- classDef distributesSBOM stroke:green,stroke-width:3px;
- classDef verifiesSBOM stroke:#07f,stroke-width:3px;
-
- %%
- class author_importer verifiesSBOM
- class author_owner createsSBOM
- class manufacturer_owner createsSBOM
- class author assemblesSBOM
- class package_importer verifiesSBOM
- class package_patcher updatesSBOM
- class package_packager assemblesSBOM
- class package_curator distributesSBOM
- class package_distributor distributesSBOM
- class language_importer verifiesSBOM
- class language_packager assemblesSBOM
- class language_steward updatesSBOM
- class language_curator distributesSBOM
- class language_distributor distributesSBOM
- class repository_distributor distributesSBOM
- class integrator_importer verifiesSBOM
- class integrator_owner createsSBOM
- class integrator_developer assemblesSBOM
- class integrator_publisher distributesSBOM
- class integrator_builder assemblesSBOM
- class integrator_checker verifiesSBOM
- class deployer assemblesSBOM
- class redactor distributesSBOM
- class auditor_internal verifiesSBOM
- class auditor_external verifiesSBOM
-
- state "Maintainer Environment" as environment_maintainer {
- [*] --> author_importer
- [*] --> author
- author_importer --> author
- author_owner --> author
- author --> language_packager
- }
-
- [*] --> environment_maintainer
-
- state "Language Ecosystem" as ecosystem_lang {
- [*] --> language_importer
- [*] --> language_steward
- [*] --> language_curator
- [*] --> language_distributor
- language_importer --> language_distributor
- language_importer --> language_curator
- language_steward --> language_curator
- language_curator --> language_distributor
- }
-
- language_packager --> ecosystem_lang
- ecosystem_lang --> ecosystem_lang
-
- state "Public Collaboration Ecosystem" as ecosystem_repo {
- [*] --> repository_distributor
- }
-
- author --> ecosystem_repo
- ecosystem_repo --> author
-
- repository_distributor --> contributor
- contributor --> repository_distributor
-
- state "Package Ecosystem" as ecosystem_package {
- [*] --> package_importer
- [*] --> package_packager
- [*] --> package_patcher
- package_importer --> package_patcher
- package_importer --> package_packager
- package_patcher --> package_packager
- package_packager --> package_curator
- package_packager --> package_distributor
- package_curator --> package_distributor
- }
-
- repository_distributor --> ecosystem_package
- language_distributor --> ecosystem_package
- ecosystem_package --> ecosystem_package
-
- state "Integrator Environment" as environment_integrator {
- [*] --> integrator_developer
- [*] --> integrator_importer
- integrator_importer --> integrator_developer
- integrator_owner --> integrator_developer
- integrator_builder --> integrator_publisher
- integrator_developer --> integrator_checker
- integrator_checker --> integrator_developer
- auditor_internal --> integrator_developer
- integrator_developer --> integrator_builder
- integrator_developer --> auditor_internal
- }
-
- repository_distributor --> environment_integrator
- language_distributor --> environment_integrator
- package_distributor --> environment_integrator
-
- state "Production Environment" as environment_prod {
- [*] --> deployer
- deployer --> redactor
- }
-
- integrator_publisher --> [*]
- integrator_developer --> environment_prod
- integrator_builder --> environment_prod
- integrator_publisher --> environment_prod
-
- deployer --> auditor_external
- deployer --> consumer
- redactor --> consumer
-
-
-
-
-
-
----
-config:
- look: neo
----
-flowchart RL
- subgraph " "
- A5@{ shape: manual-file, label: "a label"}
- B5@{ shape: manual-input, label: "a label" }
- C5@{ shape: mul-doc, label: "a label" }
- D5@{ shape: mul-proc, label: "a label" }
- E5@{ shape: paper-tape, label: "a label" }
- B3@{ shape: das, label: "a label" }
- C3@{ shape: disk, label: "a label" }
- D4@{ shape: lin-doc, label: "a label" }
- E4@{ shape: loop-limit, label: "a label" }
- end
- subgraph " "
- B6@{ shape: summary, label: "a label" }
- C6@{ shape: tag-we-rect, label: "a label" }
- D6@{ shape: tag-rect, label: "a label" }
- A2@{ shape: fork}
- B2@{ shape: hourglass }
- C2@{ shape: comment, label: "I am a comment" }
- D2@{ shape: bolt }
- D3@{ shape: disp, label: "a label" }
- C4@{ shape: junction, label: "a label" }
- A4@{ shape: extract, label: "a label"}
- B52[a fr]@{ shape: fr }
- end
- subgraph " "
- A1@{ shape: text, label: This is a textblock}
- B1@{ shape: card, label: "a label" }
- C1@{ shape: lined-proc, label: "a label" }
- D1@{ shape: start, label: "a label" }
- E1@{ shape: stop, label: "a label" }
- E2@{ shape: doc, label: "a label" }
- A6@{ shape: stored-data, label: "a label"}
- A3@{ shape: delay, label: "a label" }
- E3@{ shape: div-proc, label: "a label" }
- B4[a label]@{ shape: win-pane }
- end
-
-
----
- title: hello2
- config:
- look: handDrawn
- elk:
-
----
-%%{init: {"flowchart": {"defaultRenderer": "elk"}} }%%
-flowchart TD
-
- A([Start]) -->|go to booking page| B("select
- ISBS booking no")
- A --> QQ{cancel booking}
- A --> RR{no show}
- A --> SS{change booking}
- B -->C(wmpay_request_payment.request_type= 'partial',
- wmpay_request_payment.status= 'paid',
- pos_booking.booking_status= ‘partial’ and 'full_deposit')
- style C text-align:left
- C -->D{manage booking}
-
- D -->|cancel|E[ระบบแสดงช่องให้กรอกเหตุผล]
- E -->F{กดปุ่ม 'cancel' หรือไม่}
- F -->|Yes|G[ระบบบันทึกค่าใหม่
- และไม่สามารถแก้ไขข้อมูลได้]
- F -->|No|H[กดปุ่ม 'close']
- H -->|ระบบไม่เปลี่ยนแปลงข้อมูล|Z
- G -->|ระบบส่งข้อมูล|I[(POS_database)]
- I -->|pos_booking.booking_status='cancel'|Z([End])
-
-
- D -->|no show|J[ระบบแสดงช่องให้กรอกเหตุผล]
- J -->K{กดปุ่ม 'noshow' หรือไม่}
- K -->|Yes|L[ระบบสร้างใบเสร็จอัตโนมัติ
- Product_id: 439,
- ItemName: no show]
- style L text-align:left
-
- K -->|No|O[กดปุ่ม 'close']
- O -->|ระบบไม่เปลี่ยนแปลงข้อมูล|Z
- L -->M[ระบบบันทึกค่าใหม่]
- M -->|ระบบส่งข้อมูล|N[(POS_database)]
- N -->|pos_booking.booking_status=‘noshow’|Z
-
-
-
-
- ---- - title: hello2 - config: - look: handDrawn - layout: dagre - elk: - nodePlacementStrategy: BRANDES_KOEPF ---- -flowchart - A --> A - subgraph A - B --> B - subgraph B - C - end - end - - --
---- -config: - look: handdrawn - flowchart: - htmlLabels: true ---- -flowchart - A[I am a long text, where do I go??? handdrawn - true] --
---- -config: - flowchart: - htmlLabels: false ---- -flowchart - A[I am a long text, where do I go??? classic - false] --
---- -config: - flowchart: - htmlLabels: true ---- -flowchart - A[I am a long text, where do I go??? classic - true] --
-flowchart LR - id1(Start)-->id2(Stop) - style id1 fill:#f9f,stroke:#333,stroke-width:4px - style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5 - - -- -
- flowchart LR - A:::foo & B:::bar --> C:::foobar - classDef foo stroke:#f00 - classDef bar stroke:#0f0 - classDef ash color:red - class C ash - style C stroke:#00f, fill:black - --
- stateDiagram
- A:::foo
- B:::bar --> C:::foobar
- classDef foo stroke:#f00
- classDef bar stroke:#0f0
- style C stroke:#00f, fill:black, color:white
-
+kanban
+ id2[In progress]
+ docs[Create Blog about the new diagram]@{ priority: 'Very Low', ticket: MC-2037, assigned: 'knsv' }
-
-flowchart TB
- A@{
- label: "aksljhf kasjdh"
- }
+---
+config:
+ kanban:
+ ticketBaseUrl: 'https://mermaidchart.atlassian.net/browse/#TICKET#'
+ # sectionWidth: 300
+---
+kanban
+ Todo
+ [Create Documentation]
+ docs[Create Blog about the new diagram]
+ id7[In progress]
+ id6[Create renderer so that it works in all cases. We also add som extra text here for testing purposes. And some more just for the extra flare.]
+ id9[Ready for deploy]
+ id8[Design grammar]@{ assigned: 'knsv' }
+ id10[Ready for test]
+ id4[Create parsing tests]@{ ticket: MC-2038, assigned: 'K.Sveidqvist', priority: 'High' }
+ id66[last item]@{ priority: 'Very Low', assigned: 'knsv' }
+ id11[Done]
+ id5[define getData]
+ id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char]@{ ticket: MC-2036, priority: 'Very High'}
+ id3[Update DB function]@{ ticket: MC-2037, assigned: knsv, priority: 'High' }
+
+ id12[Can't reproduce]
+ id3[Weird flickering in Firefox]