feat: improve mission asset operations
This commit is contained in:
@@ -3,19 +3,22 @@
|
||||
|
||||
{% block content %}
|
||||
{% include "_mission_ops_tabs.html" %}
|
||||
{% macro render_end_at_field(end_at_value) %}
|
||||
{{ datetime_picker_field('End At', 'end_at', end_at_value, field_id='entry-end-at-input', wrapper_class='field-span-two mission-datetime-field', wrapper_id='entry-end-at-field') }}
|
||||
{% set field_error_map = field_errors|default({}, true) %}
|
||||
{% macro render_end_at_field(end_at_value, has_error=False) %}
|
||||
{{ datetime_picker_field('End At', 'end_at', end_at_value, field_id='entry-end-at-input', wrapper_class='field-span-two mission-datetime-field', wrapper_id='entry-end-at-field', error=has_error) }}
|
||||
{% endmacro %}
|
||||
{% macro render_state_node_row(node, row_index) %}
|
||||
<div class="state-node-row" data-state-node-row>
|
||||
{% macro render_state_node_row(node, row_index, field_error_map) %}
|
||||
{% set title_error = field_error_map.get('state_node_title:' ~ row_index) %}
|
||||
{% set at_error = field_error_map.get('state_node_at:' ~ row_index) %}
|
||||
<div class="state-node-row{% if title_error or at_error %} state-node-row-error{% endif %}" data-state-node-row{% if title_error or at_error %} data-field-error="true"{% endif %}>
|
||||
<input type="hidden" name="state_node_id" value="{{ node.id if node else '' }}">
|
||||
|
||||
<label>
|
||||
<label class="{% if title_error %}field-error-shell{% endif %}"{% if title_error %} data-field-error="true"{% endif %}>
|
||||
<span class="field-label">Node Title</span>
|
||||
<input type="text" name="state_node_title" value="{{ node.title if node else '' }}" placeholder="State Node Title">
|
||||
<input class="{% if title_error %}field-error-input{% endif %}" type="text" name="state_node_title" value="{{ node.title if node else '' }}" placeholder="State Node Title">
|
||||
</label>
|
||||
|
||||
{{ datetime_picker_field('Node At', 'state_node_at', node.at if node else '', field_id='state-node-at-' ~ row_index, wrapper_class='state-node-datetime') }}
|
||||
{{ datetime_picker_field('Node At', 'state_node_at', node.at if node else '', field_id='state-node-at-' ~ row_index, wrapper_class='state-node-datetime', error=at_error) }}
|
||||
|
||||
<label class="state-node-detail-field">
|
||||
<span class="field-label">Node Detail</span>
|
||||
@@ -43,69 +46,70 @@
|
||||
<input type="text" value="{{ asset.name }}" disabled>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<label class="{% if field_error_map.get('entry_kind') %}field-error-shell{% endif %}"{% if field_error_map.get('entry_kind') %} data-field-error="true"{% endif %}>
|
||||
<span class="field-label">Entry Type</span>
|
||||
<select id="entry-kind-select" name="entry_kind">
|
||||
<select id="entry-kind-select" name="entry_kind" class="{% if field_error_map.get('entry_kind') %}field-error-input{% endif %}">
|
||||
{% for option in kind_options %}
|
||||
<option value="{{ option.value }}" {% if option.value == form_values.entry_kind %}selected{% endif %}>{{ option.label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<label class="{% if field_error_map.get('location') %}field-error-shell{% endif %}"{% if field_error_map.get('location') %} data-field-error="true"{% endif %}>
|
||||
<span class="field-label">Location</span>
|
||||
<input type="text" name="location" value="{{ form_values.location }}">
|
||||
<input class="{% if field_error_map.get('location') %}field-error-input{% endif %}" type="text" name="location" value="{{ form_values.location }}">
|
||||
</label>
|
||||
|
||||
<label class="field-span-three">
|
||||
<label class="field-span-three{% if field_error_map.get('title') %} field-error-shell{% endif %}"{% if field_error_map.get('title') %} data-field-error="true"{% endif %}>
|
||||
<span class="field-label">Title</span>
|
||||
<input type="text" name="title" value="{{ form_values.title }}" required>
|
||||
<input class="{% if field_error_map.get('title') %}field-error-input{% endif %}" type="text" name="title" value="{{ form_values.title }}" required>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<label class="{% if field_error_map.get('state_label') %}field-error-shell{% endif %}"{% if field_error_map.get('state_label') %} data-field-error="true"{% endif %}>
|
||||
<span class="field-label">State Label</span>
|
||||
<input type="text" name="state_label" value="{{ form_values.state_label }}">
|
||||
<input class="{% if field_error_map.get('state_label') %}field-error-input{% endif %}" type="text" name="state_label" value="{{ form_values.state_label }}">
|
||||
<small class="field-hint">可单独设置显示标签;多个标签用分号分隔。State Interval 留空时使用 Title。</small>
|
||||
</label>
|
||||
|
||||
<label class="field-span-two">
|
||||
<label class="field-span-two{% if field_error_map.get('mission_label') %} field-error-shell{% endif %}"{% if field_error_map.get('mission_label') %} data-field-error="true"{% endif %}>
|
||||
<span class="field-label">Mission Label</span>
|
||||
<input type="text" name="mission_label" value="{{ form_values.mission_label }}">
|
||||
<input class="{% if field_error_map.get('mission_label') %}field-error-input{% endif %}" type="text" name="mission_label" value="{{ form_values.mission_label }}">
|
||||
<small class="field-hint">多个 Mission Label 可用分号分隔。</small>
|
||||
</label>
|
||||
|
||||
{{ datetime_picker_field('At' if is_event_kind else 'Start At', 'start_at', form_values.start_at, field_id='entry-start-at-input', required=True, wrapper_class='field-span-two mission-datetime-field', wrapper_id='entry-start-at-field', label_id='entry-start-at-label') }}
|
||||
{{ datetime_picker_field('At' if is_event_kind else 'Start At', 'start_at', form_values.start_at, field_id='entry-start-at-input', required=True, wrapper_class='field-span-two mission-datetime-field', wrapper_id='entry-start-at-field', label_id='entry-start-at-label', error=field_error_map.get('start_at')) }}
|
||||
|
||||
{% if not is_event_kind %}
|
||||
{{ render_end_at_field(form_values.end_at) }}
|
||||
{{ render_end_at_field(form_values.end_at, field_error_map.get('end_at')) }}
|
||||
{% endif %}
|
||||
|
||||
<div class="field-span-three state-node-panel" id="state-node-panel" {% if is_event_kind %}hidden{% endif %}>
|
||||
<div class="field-span-three state-node-panel{% if field_error_map.get('state_nodes') %} field-error-shell{% endif %}" id="state-node-panel" {% if is_event_kind %}hidden{% endif %}{% if field_error_map.get('state_nodes') %} data-field-error="true"{% endif %}>
|
||||
<div class="state-node-panel-header">
|
||||
<div>
|
||||
<span class="field-label">State Nodes</span>
|
||||
<p class="field-hint">每个 State Node 包含时间、标题和 Node Detail,并会在 Timeline 的 Event Point 泳道中显示。</p>
|
||||
<p class="field-hint">State Node 时间必须落在当前 State Interval 的 Start At 和 End At 之间。</p>
|
||||
</div>
|
||||
<button class="secondary-button" type="button" data-state-node-add>新增 State Node</button>
|
||||
</div>
|
||||
|
||||
<div class="state-node-list" data-state-node-list>
|
||||
{% for node in form_values.state_nodes %}
|
||||
{{ render_state_node_row(node, loop.index0) }}
|
||||
{{ render_state_node_row(node, loop.index0, field_error_map) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<p class="small-muted state-node-empty" data-state-node-empty {% if form_values.state_nodes %}hidden{% endif %}>当前没有 State Node,可按需添加。</p>
|
||||
</div>
|
||||
|
||||
<label class="field-span-three">
|
||||
<label class="field-span-three{% if field_error_map.get('summary') %} field-error-shell{% endif %}"{% if field_error_map.get('summary') %} data-field-error="true"{% endif %}>
|
||||
<span class="field-label">Summary</span>
|
||||
<textarea name="summary" rows="4">{{ form_values.summary }}</textarea>
|
||||
<textarea class="{% if field_error_map.get('summary') %}field-error-input{% endif %}" name="summary" rows="4">{{ form_values.summary }}</textarea>
|
||||
</label>
|
||||
|
||||
<label class="field-span-three">
|
||||
<label class="field-span-three{% if field_error_map.get('note') %} field-error-shell{% endif %}"{% if field_error_map.get('note') %} data-field-error="true"{% endif %}>
|
||||
<span class="field-label">Note</span>
|
||||
<textarea name="note" rows="4">{{ form_values.note }}</textarea>
|
||||
<textarea class="{% if field_error_map.get('note') %}field-error-input{% endif %}" name="note" rows="4">{{ form_values.note }}</textarea>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -127,13 +131,15 @@
|
||||
{% endif %}
|
||||
|
||||
<template id="entry-end-at-template">
|
||||
{{ render_end_at_field(form_values.end_at) }}
|
||||
{{ render_end_at_field(form_values.end_at, false) }}
|
||||
</template>
|
||||
|
||||
<template id="state-node-row-template">
|
||||
{{ render_state_node_row(none, '__INDEX__') }}
|
||||
{{ render_state_node_row(none, '__INDEX__', {}) }}
|
||||
</template>
|
||||
|
||||
{% include "_validation_dialog.html" %}
|
||||
|
||||
<script>
|
||||
(() => {
|
||||
const kindField = document.getElementById("entry-kind-select");
|
||||
|
||||
Reference in New Issue
Block a user