v1.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. namespace zin;
  3. require_once dirname(__DIR__) . DS . 'idlabel' . DS . 'v1.php';
  4. class entityTitle extends wg
  5. {
  6. /**
  7. * @var mixed[]
  8. */
  9. protected static $defineProps = array
  10. (
  11. 'id?: string|int', // 对象 ID。
  12. 'idClass?: array|string', // ID 类名。
  13. 'title?: string', // 标题文本。
  14. 'inline?: bool', // 是否启用内联样式。
  15. 'url?: string|bool', // 标题链接。
  16. 'object?: object', // 对象。
  17. 'deleted?: bool', // 是否已删除。
  18. 'type?: string', // 对象类型。
  19. 'color?: string', // 颜色。
  20. 'gap?: string|int', // 间隔。
  21. 'linkProps?: array', // 链接属性。
  22. 'titleProps?: array', // 标题属性。
  23. 'titleClass?: array|string', // 标签类名。
  24. 'joiner?: string="/"', // 连接符。
  25. 'joinerClass?: array|string', // 连接符类名。
  26. 'parentId?: string|int', // 父级对象 ID。
  27. 'parentTitle?: string', // 父级标题文本。
  28. 'parentUrl?: string|bool', // 父级标题链接。
  29. 'parent?: object', // 父级对象。
  30. 'parentType?: string', // 父级对象类型。
  31. 'parentColor?: string', // 父级颜色。
  32. 'parentClass?: array|string', // 父级类名。
  33. 'parentTitleProps?: array|string', // 父级标题属性。
  34. 'parentTitleClass?: array|string' // 父级标签类名。
  35. );
  36. /**
  37. * @var mixed[]
  38. */
  39. protected static $defineBlocks = array
  40. (
  41. 'prefix' => array(),
  42. 'leading' => array(),
  43. 'suffix' => array()
  44. );
  45. protected function created()
  46. {
  47. $object = $this->prop('object');
  48. if($object)
  49. {
  50. if(!$this->hasProp('id') && isset($object->id)) $this->setProp('id', $object->id);
  51. if(!$this->hasProp('title') && (isset($object->title) or isset($object->name))) $this->setProp('title', isset($object->title) ? $object->title : $object->name);
  52. if(!$this->hasProp('color') && isset($object->color)) $this->setProp('color', $object->color);
  53. if(!$this->hasProp('url') && isset($object->url)) $this->setProp('url', $object->url);
  54. if(!$this->hasProp('deleted') && isset($object->deleted)) $this->setProp('deleted', $object->deleted);
  55. if(!$this->hasProp('parent') && isset($object->parent)) $this->setProp('parent', $object->parent);
  56. }
  57. $parent = $this->prop('parent');
  58. if($parent)
  59. {
  60. if(!$this->hasProp('parentId') && isset($parent->id)) $this->setProp('parentId', $parent->id);
  61. if(!$this->hasProp('parentTitle') && (isset($parent->title) or isset($parent->name))) $this->setProp('parentTitle', isset($parent->title) ? $parent->title : $parent->name);
  62. if(!$this->hasProp('parentUrl') && isset($parent->url)) $this->setProp('parentUrl', $parent->url);
  63. if(!$this->hasProp('parentColor') && isset($parent->color)) $this->setProp('parentColor', $parent->color);
  64. }
  65. }
  66. protected function buildTitle()
  67. {
  68. global $lang;
  69. list($id, $title, $url, $type, $color, $titleProps, $titleClass, $deleted) = $this->prop(array('id', 'title', 'url', 'type', 'color', 'titleProps', 'titleClass', 'deleted'));
  70. if($url === true && $type) $url = createLink($type, 'view', $type . 'ID={id}');
  71. if(is_string($url) && $id) $url = str_replace('{id}', "$id", $url);
  72. return array
  73. (
  74. $id ? idLabel::create($id, array('class' => array($this->prop('idClass'), $this->prop('inline') ? 'mr-' . $this->prop('gap', 2) : ''))) : null,
  75. $this->block('leading'),
  76. $this->buildParentTitle(),
  77. is_string($url) ?
  78. a(
  79. setClass('entity-title-link max-w-lg', $titleClass),
  80. set::href($url),
  81. set::title($title),
  82. set($titleProps),
  83. set($this->prop('linkProps')),
  84. $color ? setStyle('color', $color) : null,
  85. $title
  86. ) : span
  87. (
  88. setClass('entity-title-text', $titleClass),
  89. set($titleProps),
  90. $color ? setStyle('color', $color) : null,
  91. $title
  92. ),
  93. $deleted ? span(setClass('label danger'), $lang->deleted) : null
  94. );
  95. }
  96. protected function buildParentTitle()
  97. {
  98. $parentTitle = $this->prop('parentTitle');
  99. if(!isset($parentTitle)) return null;
  100. list($parentID, $parent, $parentUrl, $parentType, $parentColor, $parentClass, $parentTitleProps, $parentTitleClass, $joiner, $joinerClass) = $this->prop(array('parentId', 'parent', 'parentUrl', 'parentType', 'parentColor', 'parentClass', 'parentTitleProps', 'parentTitleClass', 'joiner', 'joinerClass'));
  101. return array
  102. (
  103. new entityTitle
  104. (
  105. setClass($parentClass),
  106. set::object($parent),
  107. set::id($parentID),
  108. set::title($parentTitle),
  109. set::url($parentUrl),
  110. set::color($parentColor),
  111. set::type($parentType),
  112. set::titleProps($parentTitleProps),
  113. set::titleClass($parentTitleClass)
  114. ),
  115. $joiner ? span(setClass('entity-title-joiner', $joinerClass), $joiner) : null
  116. );
  117. }
  118. protected function build()
  119. {
  120. /* Convert line break to space on copy. 复制时将换行转换为空格。see https://back.zcorp.cc/pms/ticket-view-1334.html */
  121. $handleCopy = <<<'JS'
  122. const lines = document.getSelection().toString().split('\n');
  123. event.clipboardData.setData('text/plain', lines.join(' '));
  124. event.preventDefault();
  125. JS;
  126. return div
  127. (
  128. setClass('entity-title', $this->prop('inline') ? '' : 'row items-center gap-' . $this->prop('gap', 2)),
  129. set($this->getRestProps()),
  130. $this->block('prefix'),
  131. $this->buildTitle(),
  132. $this->children(),
  133. $this->block('suffix'),
  134. on::copy()->do($handleCopy)
  135. );
  136. }
  137. }