How should I do for making a tiny resource inspector editor?

Godot Version

4.2.1

Question

I want to make a tiny resource inspector plugin for my working, that I can click a resource in file pane, and I can edit array of objects, and also I can easily click a button to parse CSV to array of objects. (and it could popup an alert window to alert user parsing CSV will replace any data in array)

However, I can not clearly understand documents on official site.
I tried to programming but nothing happened. I don’t know why and what should I do.

here is my code.

dialog_resource_support_editor.gd

@tool
extends EditorPlugin

var plugin = preload("res://addons/dialog_resource_support_editor/inspector_plugin.gd")

func _enter_tree():
    plugin = plugin.new()
    add_inspector_plugin(plugin)

func _exit_tree():
    if is_instance_valid(plugin):
        remove_inspector_plugin(plugin)
        plugin = null
----
inspector_plugin.gd

extends EditorInspectorPlugin

var propery_editor = preload("res://addons/dialog_resource_support_editor/editor_property.gd")

func _can_handle(object):
    return object is Array[DialogCommand]
    
func _parse_property(object, type, name, hint_type, hint_string, usage_flags, wide):
    if name == "list":
        var property = propery_editor.new()
        property.command_changed.connect(func(command_list: Array[DialogCommand]): object.set(name, command_list))
        add_property_editor(name, property)
        return true
    
    return false
-----
editor_property.gd

extends EditorProperty

signal command_changed(current_value: Array[DialogCommand])

var property_control = Button.new()
var updating = false

var current_value : Array[DialogCommand]
var fd : EditorFileDialog

func _init():
    property_control.text = "Load CSV Scenario File"
    
    add_child(property_control)
    add_focusable(property_control)
    property_control.pressed.connect(_on_button_pressed)
    
    fd = EditorFileDialog.new()
    fd.file_mode = EditorFileDialog.FILE_MODE_OPEN_FILE
    fd.access = EditorFileDialog.ACCESS_FILESYSTEM
    fd.add_filter("*.csv", "CSV File")
    fd.file_selected.connect(_on_fd_file_selected)

func _on_button_pressed():
    if updating:
        return
        
    fd.popup_file_dialog()

func _on_fd_file_selected(path):
    var load_file = FileAccess.open(path, FileAccess.READ)
    if not FileAccess.file_exists(path):
        print("File not Exist: ", path)
        return
    
    _parsing_csv(load_file)

func _update_property():
    var new_value = get_edited_object()[get_edited_property()]
    if new_value == current_value:
        return
    
    updating = true
    current_value = new_value
    updating = false

func _parsing_csv(file):
    if not file:
        print("Load File Error")
        return
    
    current_value.clear()
    
    var items_title = file.get_csv_line(",")
    while file.get_position() < file.get_length():
        var items : PackedStringArray = file.get_csv_line(",")
        var command = DialogCommand.new()
        command.type = DialogCommand.Type.get(items[0])
        if items[1] == "TRUE":
            command.is_skippable = true
        else:
            command.is_skippable = false
        command.actor = items[2]
        command.content = items[3]
        command.config = items[4]
        command.memo = items[5]
        
        current_value.append(command)
    
    command_changed.emit(current_value)
------
dialog_command.gd

extends Resource
class_name DialogCommand

enum Type {SERIF, SET_BG, BG, 
BGM, SE, 
SET_CHARA, SET_FACE, DELETE_CHARA, 
SET_BLACK, FADE_IN, FADE_OUT,
IF, SELECT, JUMP, LABEL, SWITCH, VARIABLE,
ITEM, SHOP,
PARTY_MEMBER}

@export var type : Type
@export var is_skippable : bool
@export var actor : String
@export_multiline var content : String
@export var config : Dictionary
@export var memo : String
------
dialog_command_group.gd

extends Resource
class_name DialogCommandGroup

@export var list : Array[DialogCommand]