You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by jo...@apache.org on 2022/03/27 19:28:14 UTC

[isis] 03/03: ISIS-2957 ResponseHandler chain based on stats

This is an automated email from the ASF dual-hosted git repository.

joergrade pushed a commit to branch ISIS-2957
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 5c906d647d520b20ff03fd10fd169a79e5785dbb
Author: Jörg Rade <jo...@kuehne-nagel.com>
AuthorDate: Sun Mar 27 21:27:27 2022 +0200

    ISIS-2957 ResponseHandler chain based on stats
---
 .../kroviz/core/aggregator/ActionDispatcher.kt     |   2 +-
 .../isis/client/kroviz/handler/BaseHandler.kt      |   2 +
 .../isis/client/kroviz/handler/PlainHandlers.kt    |   7 -
 .../isis/client/kroviz/handler/ResponseHandler.kt  |  81 ++++---
 .../isis/client/kroviz/handler/TObjectHandler.kt   |  41 ++++
 .../apache/isis/client/kroviz/ui/core/RoMenuBar.kt |  20 +-
 .../isis/client/kroviz/ui/core/SessionManager.kt   |  12 ++
 .../client/kroviz/ui/panel/DynamicMenuBuilder.kt   |   6 -
 .../isis/client/kroviz/ui/panel/EventPieChart.kt   | 237 ---------------------
 .../apache/isis/client/kroviz/utils/IconManager.kt |   1 -
 10 files changed, 114 insertions(+), 295 deletions(-)

diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ActionDispatcher.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ActionDispatcher.kt
index 4ed1d7c..91ab86e 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ActionDispatcher.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ActionDispatcher.kt
@@ -51,7 +51,7 @@ class ActionDispatcher(private val at: Point = Point(100, 100)) : BaseAggregator
             to is Restful -> {}
             else -> {
                 console.log(to)
-                throw Throwable("[ActionDispatcher.update] ${to!!::class.simpleName}")
+//                throw Throwable("[ActionDispatcher.update] ${to!!::class.simpleName}")
             }
         }
     }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/BaseHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/BaseHandler.kt
index dd57b46..83d1b2a 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/BaseHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/BaseHandler.kt
@@ -21,6 +21,7 @@ package org.apache.isis.client.kroviz.handler
 import org.apache.isis.client.kroviz.core.event.LogEntry
 import org.apache.isis.client.kroviz.to.TransferObject
 import org.apache.isis.client.kroviz.ui.core.Constants
+ import org.apache.isis.client.kroviz.ui.core.SessionManager
 
 /**
  * Handle responses to XmlHttpRequests asynchronously,
@@ -76,6 +77,7 @@ abstract class BaseHandler {
     }
 
     open fun update() {
+        SessionManager.logInvocation(this)
         logEntry.getAggregator()?.update(logEntry, Constants.subTypeJson)
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/PlainHandlers.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/PlainHandlers.kt
index 234db7a..069bce9 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/PlainHandlers.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/PlainHandlers.kt
@@ -63,13 +63,6 @@ class ServiceHandler : BaseHandler() {
     }
 }
 
-class TObjectHandler : BaseHandler() {
-
-    override fun parse(response: String): TransferObject {
-        return Json.decodeFromString<TObject>(response)
-    }
-}
-
 class UserHandler : BaseHandler() {
 
     override fun parse(response: String): TransferObject {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResponseHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResponseHandler.kt
index f777f2d..b4ae3f5 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResponseHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResponseHandler.kt
@@ -27,56 +27,55 @@ import org.apache.isis.client.kroviz.core.event.LogEntry
 object ResponseHandler {
     private var delegate: BaseHandler
 
-    //IMPROVE sequence of handlers should follow frequency of invocation in order to minimize the time taken by unneeded calls to 'canHandle()'
-    private var _0 = RestfulHandler()
-    private var _0a = VersionHandler()
-    private var _0b = DomainTypesHandler()
-    private var _1 = MenuBarsHandler()
-    private var _2 = ActionHandler()
-    private var _3 = ServiceHandler()
-    private var _4 = ResultListHandler()
-    private var _4a = ResultObjectHandler()
-    private var _4b = ResultValueHandler()
-    private var _6 = LayoutHandler()
-    private var _6a = LayoutXmlHandler()
-    private var _7 = CollectionHandler()
-    private var _7a = PropertyHandler()
-    private var _7b = TObjectHandler()
-    private var _8 = MemberHandler()
-    private var _9 = HttpErrorHandler()
-    private var _9a = Http401ErrorHandler()
-    private var _10 = UserHandler()
-    private var _13 = DomainTypeHandler()
-    private var _14 = DiagramHandler()
-    private var _15 = IconHandler()
+    //sequence of handlers follows frequency of invocation (demo execute all menu actions)
+    //IMPROVE by dynamic lookup at runtime?
+    private var _1 = TObjectHandler()
+    private var _2 = LayoutXmlHandler()
+    private var _3 = CollectionHandler()
+    private var _4 = ActionHandler()
+    private var _5 = HttpErrorHandler()
+    private var _6 = RestfulHandler()
+    private var _7 = VersionHandler()
+    private var _8 = MenuBarsHandler()
+
+    private var _9 = DomainTypesHandler()
+    private var _10 = ServiceHandler()
+    private var _11 = ResultListHandler()
+    private var _12 = ResultObjectHandler()
+    private var _13 = ResultValueHandler()
+    private var _14 = LayoutHandler()
+    private var _15 = PropertyHandler()
+    private var _16 = MemberHandler()
+    private var _17 = Http401ErrorHandler()
+    private var _18 = UserHandler()
+    private var _19 = DomainTypeHandler()
+    private var _20 = DiagramHandler()
+    private var _21 = IconHandler()
     private var last = DefaultHandler()
 
     init {
-        delegate = _0
-        _0.successor = _0a
-        _0a.successor = _0b
-        _0b.successor = _1
+        delegate = _1
         _1.successor = _2
         _2.successor = _3
         _3.successor = _4
-        _4.successor = _4a
-        _4a.successor = _4b
-        _4b.successor = _6
-//        _5.successor = _6
-        _6.successor = _6a
-        _6a.successor = _7
-        _7.successor = _7a
-        _7a.successor = _7b
-        _7b.successor = _8
+        _4.successor = _5
+        _5.successor = _6
+        _6.successor = _7
+        _7.successor = _8
         _8.successor = _9
-        _9.successor = _9a
-        _9a.successor = _10
-        _10.successor = _13
-//        _11.successor = _12
-//        _12.successor = _13
+        _9.successor = _10
+        _10.successor = _11
+        _11.successor = _12
+        _12.successor = _13
         _13.successor = _14
         _14.successor = _15
-        _15.successor = last
+        _15.successor = _16
+        _16.successor = _17
+        _17.successor = _18
+        _18.successor = _19
+        _19.successor = _20
+        _20.successor = _21
+        _21.successor = last
     }
 
     fun handle(logEntry: LogEntry) {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/TObjectHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/TObjectHandler.kt
new file mode 100644
index 0000000..36806fd
--- /dev/null
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/TObjectHandler.kt
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.client.kroviz.handler
+
+import kotlinx.serialization.decodeFromString
+import kotlinx.serialization.json.Json
+import org.apache.isis.client.kroviz.to.TObject
+import org.apache.isis.client.kroviz.to.TransferObject
+
+class TObjectHandler : BaseHandler() {
+
+    override fun canHandle(response: String): Boolean {
+        val urlPath = logEntry.url.split("restful")
+        val path = urlPath[1]
+        if (path != null && path.length > 1) {
+            return super.canHandle(response)
+        }
+        return false
+    }
+
+    override fun parse(response: String): TransferObject {
+        return Json.decodeFromString<TObject>(response)
+    }
+
+}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoMenuBar.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoMenuBar.kt
index 534f8a0..7e91a47 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoMenuBar.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoMenuBar.kt
@@ -33,8 +33,13 @@ import io.kvision.utils.px
 import org.apache.isis.client.kroviz.core.Session
 import org.apache.isis.client.kroviz.core.event.ResourceProxy
 import org.apache.isis.client.kroviz.to.mb.Menubars
-import org.apache.isis.client.kroviz.ui.dialog.*
-import org.apache.isis.client.kroviz.ui.panel.*
+import org.apache.isis.client.kroviz.ui.dialog.About
+import org.apache.isis.client.kroviz.ui.dialog.EventDialog
+import org.apache.isis.client.kroviz.ui.dialog.LoginPrompt
+import org.apache.isis.client.kroviz.ui.dialog.SvgInline
+import org.apache.isis.client.kroviz.ui.panel.GeoMap
+import org.apache.isis.client.kroviz.ui.panel.ImageSample
+import org.apache.isis.client.kroviz.ui.panel.SvgMap
 import org.apache.isis.client.kroviz.utils.IconManager
 import org.apache.isis.client.kroviz.utils.Point
 
@@ -186,6 +191,11 @@ class RoMenuBar : SimplePanel() {
             buildMenuEntry(testTitle, "Test", { this.executeAllMenuBarActions() })
         )
 
+        val stats = "Log Handler Stats"
+        mainMenu.add(
+            buildMenuEntry(stats, "Console", { this.logStats() })
+        )
+
         /*
                val testTitle = "Test"
                  mainMenu.add(
@@ -234,4 +244,10 @@ class RoMenuBar : SimplePanel() {
         }
     }
 
+    fun logStats() {
+        SessionManager.responseHandlerStatistics.forEach {
+            console.log("${it.key} -> ${it.value}")
+        }
+    }
+
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/SessionManager.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/SessionManager.kt
index 98496dc..173177c 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/SessionManager.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/SessionManager.kt
@@ -20,6 +20,7 @@ package org.apache.isis.client.kroviz.ui.core
 
 import org.apache.isis.client.kroviz.core.Session
 import org.apache.isis.client.kroviz.core.event.EventStore
+import org.apache.isis.client.kroviz.handler.BaseHandler
 
 /**
  * Handle multiple Sessions
@@ -29,6 +30,7 @@ object SessionManager {
     private val sessions = mutableSetOf<Session>()
     private val eventStore = EventStore()
     private var activeSession: Session? = null
+    val responseHandlerStatistics = mutableMapOf<String, Int>()
 
     fun getBaseUrl(): String? {
         return activeSession?.baseUrl
@@ -69,4 +71,14 @@ object SessionManager {
         menuBar.updateIcon(activeSession!!)
     }
 
+    fun logInvocation(responseHandler: BaseHandler) {
+        val className = responseHandler::class.simpleName!!
+        val value = responseHandlerStatistics.get(className)
+        if (value == null) {
+            responseHandlerStatistics.put(className, 1)
+        } else {
+            responseHandlerStatistics.put(className, value + 1)
+        }
+    }
+
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/DynamicMenuBuilder.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/DynamicMenuBuilder.kt
index 87ce81e..f193d73 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/DynamicMenuBuilder.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/DynamicMenuBuilder.kt
@@ -62,12 +62,6 @@ class DynamicMenuBuilder {
         })
         menu.add(bubble)
 
-        val pieTitle = "Pie Chart"
-        val pie = buildMenuEntry(pieTitle, pieTitle, {
-            ViewManager.add(pieTitle, EventPieChart())
-        })
-        menu.add(pie)
-
         return menu.toTypedArray().asDynamic()
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventPieChart.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventPieChart.kt
deleted file mode 100644
index 87ae40a..0000000
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventPieChart.kt
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.client.kroviz.ui.panel
-
-import io.kvision.chart.*
-import io.kvision.chart.js.LegendItem
-import io.kvision.core.Col
-import io.kvision.core.Color
-import io.kvision.core.CssSize
-import io.kvision.core.UNIT
-import io.kvision.panel.SimplePanel
-import io.kvision.utils.obj
-import org.apache.isis.client.kroviz.core.event.LogEntry
-import org.apache.isis.client.kroviz.ui.core.SessionManager
-import org.apache.isis.client.kroviz.utils.StringUtils
-import kotlin.math.pow
-
-/*
-new Chart(document.getElementById("doughnut-chart"), {
-    type: 'doughnut',
-    data: {
-      labels: ["Africa", "Asia", "Europe", "Latin America", "North America"],
-      datasets: [
-        {
-          label: "Population (millions)",
-          backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
-          data: [2478,5267,734,784,433]
-        }
-      ]
-    },
-    options: {
-      title: {
-        display: true,
-        text: 'Predicted world population (millions) in 2050'
-      }
-    }
-});
- */
-
-class EventPieChart : SimplePanel() {
-    private val model = SessionManager.getEventStore()
-    private var chart: Chart
-
-    init {
-        width = CssSize(90, UNIT.vw)
-        chart = chart(
-            configuration = buildConfiguration()
-        )
-    }
-
-    private fun buildConfiguration(): Configuration {
-        fun buildToolTipList(): List<String> {
-            val labelList = mutableListOf<String>()
-            model.log.forEachIndexed { i, it ->
-                val l = it.buildToolTip(i)
-                labelList.add(l)
-            }
-            return labelList
-        }
-
-        val dataSetsList = listOf(buildDataSets())
-        return Configuration(
-            type = ChartType.DOUGHNUT,
-            dataSets = dataSetsList,
-            labels = buildToolTipList(),
-            options = buildChartOptions(),
-        )
-    }
-
-    private fun buildChartOptions(): ChartOptions {
-        fun buildLegend(): LegendOptions {
-            fun buildLegendLabelList(): Array<LegendItem> {
-                val legendLabelList = mutableListOf<LegendItem>()
-                label2color.forEach {
-                    val li = obj {
-                        text = it.key
-                        fillStyle = it.value
-                    }
-                    legendLabelList.add(li as LegendItem)
-                }
-                val error = obj {
-                    text = "error"
-                    fillStyle = TRANSPARENT
-                    strokeStyle = ERROR_COLOR
-                }
-                legendLabelList.add(error as LegendItem)
-                val size = obj {
-                    text = "bubble size ^= response size"
-                    fillStyle = TRANSPARENT
-                    strokeStyle = TRANSPARENT
-                }
-                legendLabelList.add(size as LegendItem)
-                return legendLabelList.toTypedArray()
-            }
-
-            return LegendOptions(
-                display = true,
-                position = Position.RIGHT,
-                labels = LegendLabelOptions(generateLabels = {
-                    buildLegendLabelList()
-                }),
-                title = LegendTitleOptions(text = "Parallel Requests", display = true),
-            )
-        }
-
-        return ChartOptions(
-            plugins = PluginsOptions(
-                title = TitleOptions(
-                    text = listOf("Request Duration over Time by Request Parallelism and Response Size"),
-                    display = true
-                ),
-                legend = buildLegend(),
-            ),
-            showLine = true,
-            scales = mapOf(
-                "x" to ChartScales(
-                    title = ScaleTitleOptions(
-                        text = "Time since Connect(ms)", display = true
-                    )
-                ),
-                "y" to ChartScales(
-                    title = ScaleTitleOptions(text = "duration in ms (log)", display = true),
-                    type = ScalesType.LOGARITHMIC
-                )
-            )
-        )
-    }
-
-    private fun buildDataSets(): DataSets {
-        fun buildBgColorList(): List<Color> {
-            val bgColorList = mutableListOf<Color>()
-            model.log.forEach {
-                val c = it.determineBubbleColor()
-                bgColorList.add(c)
-            }
-            return bgColorList
-        }
-
-        fun buildBorderColorList(): List<Color> {
-            val borderColorList = mutableListOf<Color>()
-            model.log.forEach {
-                when {
-                    it.isError() -> borderColorList.add(ERROR_COLOR)
-                    else -> borderColorList.add(Color.name(Col.LIGHTGRAY))
-                }
-            }
-            return borderColorList
-        }
-
-        /**
-         * The term DataSets is severely miss leading:
-         * 1. a plural form is used (where actually a singular would be more appropriate) -> "a DataSets"
-         * 2. datasets are used inside datasets, data inside data
-         */
-        fun buildDataSetsList(): List<DataSets> {
-            val dataSetsList = mutableListOf<DataSets>()
-            model.log.forEach {
-                //               val d = it //.buildData()
-                //               dataSetsList.add(d)
-            }
-            return dataSetsList
-        }
-
-        return DataSets(
-            backgroundColor = buildBgColorList(),
-            borderColor = buildBorderColorList(),
-            data = buildDataSetsList(),
-        )
-    }
-
-    private fun LogEntry.buildToolTip(index: Int): String {
-        val size = StringUtils.format(this.responseLength)
-        val title = StringUtils.shortTitle(this.title)
-        return title +
-                "\nseq.no.: $index" +
-                "\nparallel runs: ${this.runningAtStart}" +
-                "\nrsp.len.: $size" +
-                "\ntype: ${this.type}"
-    }
-
-    private fun LogEntry.calculateBubbleSize(): Int {
-        val i = responseLength
-        return i.toDouble().pow(1 / 3.toDouble()).toInt()
-    }
-
-    private fun LogEntry.determineBubbleColor(): Color {
-        val i = runningAtStart
-        return when {
-            (i >= 0) && (i <= 4) -> LIGHT_BLUE
-            (i > 4) && (i <= 8) -> DARK_BLUE
-            (i > 8) && (i <= 16) -> GREEN
-            (i > 16) && (i <= 32) -> YELLOW
-            (i > 32) && (i <= 64) -> RED
-            (i > 64) && (i <= 128) -> RED_VIOLET
-            else -> VIOLET
-        }
-    }
-
-    companion object {
-        val TRANSPARENT = Color.rgba(0xFF, 0xFF, 0xFF, 0x00)
-        val ERROR_COLOR = Color.rgba(0xFF, 0x00, 0x00, 0xFF)
-        val LIGHT_BLUE = Color.rgba(0x4B, 0xAC, 0xC6, 0x80)
-        val DARK_BLUE = Color.rgba(0x4F, 0x81, 0xBD, 0x80)
-        val GREEN = Color.rgba(0x9B, 0xBB, 0x59, 0x80)
-        val YELLOW = Color.rgba(0xF7, 0x96, 0x46, 0x80)
-        val RED = Color.rgba(0xC0, 0x50, 0x4D, 0x80)
-        val RED_VIOLET = Color.rgba(0xA0, 0x5A, 0x78, 0x80)
-        val VIOLET = Color.rgba(0x80, 0x64, 0xA2, 0x80)
-
-        val label2color = mapOf(
-            "0 .. 4" to LIGHT_BLUE,
-            "5 .. 8" to DARK_BLUE,
-            "9 .. 16" to GREEN,
-            "17 .. 32" to YELLOW,
-            "33 .. 64" to RED,
-            "65 .. 128" to RED_VIOLET,
-            ">= 129" to VIOLET
-        )
-    }
-
-}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/IconManager.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/IconManager.kt
index 3e56d72..b48b67e 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/IconManager.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/IconManager.kt
@@ -88,7 +88,6 @@ object IconManager {
         "OK" to "check",
         "Open" to "book",
         "Other" to "asterisk",
-        "Pie" to "pie-chart",
         "Pin" to "map-pin",
         "Primitives" to "hashtag",
         "Properties" to "indent",