585 lines
38 KiB
PHP
585 lines
38 KiB
PHP
@extends($layout)
|
|
|
|
@section('content')
|
|
|
|
@php
|
|
$state = $state ?? null;
|
|
@endphp
|
|
|
|
<div class="pageheader">
|
|
<div class="pageicon"><span class="fa fa-suitcase"></span></div>
|
|
<div class="pagetitle">
|
|
<h5>{!! __('label.administration') !!}</h5>
|
|
<h1>{!! sprintf(__('headline.project'), $tpl->escape($project['name'])) !!}
|
|
</h1>
|
|
</div>
|
|
</div><!--pageheader-->
|
|
|
|
<div class="maincontent">
|
|
<div class="maincontentinner">
|
|
|
|
{!! $tpl->displayNotification() !!}
|
|
|
|
<div class="inlineDropDownContainer" style="float:right; z-index:9; padding-top:2px;">
|
|
|
|
<x-global::forms.button tag="a" link="{{ BASE_URL }}/projects/duplicateProject/{{ $project['id'] }}" contentRole="default" class="duplicateProjectModal" data-tippy-content="{{ __('link.duplicate_project') }}"><i class="fa-regular fa-copy"></i> Copy</x-global::forms.button>
|
|
<x-global::forms.button tag="a" state="danger" variant="outline" class="delete" link="{{ BASE_URL }}/projects/delProject/{{ $project['id'] }}" data-tippy-content="{{ __('link.delete_project') }}"><i class="fa fa-trash"></i> Delete</x-global::forms.button>
|
|
|
|
|
|
</div>
|
|
<div class="tabbedwidget tab-primary projectTabs">
|
|
|
|
<ul>
|
|
<li><a href="#projectdetails"><span class="fa fa-leaf"></span> {!! __('tabs.projectdetails') !!}</a></li>
|
|
<li><a href="#team"><span class="fa fa-group"></span> {!! __('tabs.team') !!}</a></li>
|
|
|
|
<li><a href="#integrations"> <span class="fa fa-asterisk"></span> {!! __('tabs.Integrations') !!}</a></li>
|
|
<li><a href="#todosettings"><span class="fa fa-list-ul"></span> {!! __('tabs.todosettings') !!}</a></li>
|
|
<li><a href="#masterdata"><span class="fa fa-link"></span> 主数据</a></li>
|
|
@dispatchEvent('projectTabsList')
|
|
</ul>
|
|
|
|
<div id="projectdetails">
|
|
@include('projects::submodules.projectDetails')
|
|
</div>
|
|
|
|
<div id="team">
|
|
<form method="post" action="{{ BASE_URL }}/projects/showProject/{{ $project['id'] }}#team">
|
|
<input type="hidden" name="saveUsers" value="1" />
|
|
|
|
|
|
<div class="row-fluid">
|
|
<div class="span12">
|
|
|
|
<div class="form-group">
|
|
<br />{!! __('text.choose_access_for_users') !!}<br />
|
|
<br />
|
|
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<h4 class="widgettitle title-light">
|
|
<span class="fa fa-users"></span>{!! __('headlines.team_member') !!}
|
|
</h4>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
@foreach ($project['assignedUsers'] as $userId => $assignedUser)
|
|
<div class="col-md-4">
|
|
<div class="userBox">
|
|
<input type='checkbox' name='editorId[]' id="user-{{ $assignedUser['id'] }}" value='{{ $assignedUser['id'] }}'
|
|
checked="checked"
|
|
/>
|
|
<div class="commentImage">
|
|
<img src="{{ BASE_URL }}/api/users?profileImage={{ $assignedUser['id'] }}&v={{ format($assignedUser['modified'])->timestamp() }}"/>
|
|
</div>
|
|
<label for="user-{{ $assignedUser['id'] }}" >{!! sprintf(__('text.full_name'), $tpl->escape($assignedUser['firstname']), $tpl->escape($assignedUser['lastname'])) !!}
|
|
@if ($assignedUser['jobTitle'] != '')
|
|
<small>
|
|
{{ $assignedUser['jobTitle'] }}
|
|
</small>
|
|
<br/>
|
|
@endif
|
|
@if ($assignedUser['source'] == 'api')
|
|
<small>
|
|
API Access
|
|
</small>
|
|
<br/>
|
|
@endif
|
|
@if ($assignedUser['status'] == 'i')
|
|
<small>{!! __('label.invited') !!}</small>
|
|
@endif
|
|
</label>
|
|
@php
|
|
if (($roles::getRoles()[$assignedUser['role']] == $roles::$admin || $roles::getRoles()[$assignedUser['role']] == $roles::$owner)) {
|
|
@endphp
|
|
<x-global::forms.text-input readonly disabled value="{{ __('label.roles.'.$roles::getRoles()[$assignedUser['role']]) }}" />
|
|
@php
|
|
} else {
|
|
@endphp
|
|
<select name="userProjectRole-{{ $assignedUser['id'] }}">
|
|
<option value="inherit">Inherit</option>
|
|
<option value="{{ array_search($roles::$readonly, $roles::getRoles()) }}"
|
|
@if ($assignedUser['projectRole'] == array_search($roles::$readonly, $roles::getRoles())) selected='selected' @endif
|
|
>{!! __('label.roles.'.$roles::$readonly) !!}</option>
|
|
|
|
<option value="{{ array_search($roles::$commenter, $roles::getRoles()) }}"
|
|
@if ($assignedUser['projectRole'] == array_search($roles::$commenter, $roles::getRoles())) selected='selected' @endif
|
|
>{!! __('label.roles.'.$roles::$commenter) !!}</option>
|
|
<option value="{{ array_search($roles::$editor, $roles::getRoles()) }}"
|
|
@if ($assignedUser['projectRole'] == array_search($roles::$editor, $roles::getRoles())) selected='selected' @endif
|
|
>{!! __('label.roles.'.$roles::$editor) !!}</option>
|
|
<option value="{{ array_search($roles::$manager, $roles::getRoles()) }}"
|
|
@if ($assignedUser['projectRole'] == array_search($roles::$manager, $roles::getRoles())) selected='selected' @endif
|
|
>{!! __('label.roles.'.$roles::$manager) !!}</option>
|
|
</select>
|
|
@php } @endphp
|
|
<div class="clearall"></div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
|
|
</div>
|
|
|
|
|
|
` <div class="row">
|
|
<div class="col-md-12">
|
|
<h4 class="widgettitle title-light">
|
|
<span class="fa fa-user-friends "></span>{!! __('headlines.assign_users_to_project') !!}
|
|
</h4>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
@foreach ($availableUsers as $row)
|
|
@if (collect($project['assignedUsers'])->where('id', $row['id'])->isEmpty())
|
|
<div class="col-md-4">
|
|
<div class="userBox">
|
|
<input type='checkbox' name='editorId[]' id="user-{{ $row['id'] }}" value='{{ $row['id'] }}' />
|
|
|
|
<div class="commentImage">
|
|
<img src="{{ BASE_URL }}/api/users?profileImage={{ $row['id'] }}&v={{ format($row['modified'])->timestamp() }}"/>
|
|
</div>
|
|
<label for="user-{{ $row['id'] }}" >{!! sprintf(__('text.full_name'), $tpl->escape($row['firstname']), $tpl->escape($row['lastname'])) !!}</label>
|
|
@if ($roles::getRoles()[$row['role']] == $roles::$admin || $roles::getRoles()[$row['role']] == $roles::$owner)
|
|
<x-global::forms.text-input readonly disabled value="{{ __('label.roles.'.$roles::getRoles()[$row['role']]) }}" />
|
|
@else
|
|
@php $assignedUserMatch = collect($project['assignedUsers'])->where('id', $row['id'])->first(); @endphp
|
|
<select name="userProjectRole-{{ $row['id'] }}">
|
|
<option value="inherit">Inherit</option>
|
|
<option value="{{ array_search($roles::$readonly, $roles::getRoles()) }}"
|
|
@if ($assignedUserMatch && $assignedUserMatch['projectRole'] == array_search($roles::$readonly, $roles::getRoles())) selected='selected' @endif
|
|
>{!! __('label.roles.'.$roles::$readonly) !!}</option>
|
|
|
|
<option value="{{ array_search($roles::$commenter, $roles::getRoles()) }}"
|
|
@if ($assignedUserMatch && $assignedUserMatch['projectRole'] == array_search($roles::$commenter, $roles::getRoles())) selected='selected' @endif
|
|
>{!! __('label.roles.'.$roles::$commenter) !!}</option>
|
|
<option value="{{ array_search($roles::$editor, $roles::getRoles()) }}"
|
|
@if ($assignedUserMatch && $assignedUserMatch['projectRole'] == array_search($roles::$editor, $roles::getRoles())) selected='selected' @endif
|
|
>{!! __('label.roles.'.$roles::$editor) !!}</option>
|
|
<option value="{{ array_search($roles::$manager, $roles::getRoles()) }}"
|
|
@if ($assignedUserMatch && $assignedUserMatch['projectRole'] == array_search($roles::$manager, $roles::getRoles())) selected='selected' @endif
|
|
>{!! __('label.roles.'.$roles::$manager) !!}</option>
|
|
</select>
|
|
@endif
|
|
<div class="clearall"></div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
@endif
|
|
@endforeach
|
|
@if ($login::userIsAtLeast($roles::$manager))
|
|
<div class="col-md-4">
|
|
|
|
<div class="userBox">
|
|
<a class="userEditModal" href="{{ BASE_URL }}/users/newUser?preSelectProjectId={{ $project['id'] }}" style="font-size:var(--font-size-l); line-height:61px"><span class="fa fa-user-plus"></span> {!! __('links.create_user') !!}</a>
|
|
<div class="clearall"></div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
<br/>
|
|
<x-global::forms.button tag="input" inputType="submit" contentRole="primary" :labelText="__('buttons.save')" name="saveUsers" id="save" />
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
<div id="integrations">
|
|
|
|
@if ($projectMuteCount > 0)
|
|
<div class="alert alert-info" style="margin-bottom: 20px;">
|
|
<i class="fa fa-bell-slash"></i>
|
|
{!! sprintf(__('label.project_mute_count'), $projectMuteCount) !!}
|
|
</div>
|
|
@endif
|
|
|
|
<h4 class="widgettitle title-light"><span class="fa fa-leaf"></span>Mattermost</h4>
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<img src="{{ BASE_URL }}/dist/images/mattermost-logoHorizontal.png" width="200" />
|
|
</div>
|
|
<div class="col-md-5">
|
|
{!! __('text.mattermost_instructions') !!}
|
|
</div>
|
|
<div class="col-md-4">
|
|
<strong>{!! __('label.webhook_url') !!}</strong><br />
|
|
<form action="{{ BASE_URL }}/projects/showProject/{{ $project['id'] }}#integrations" method="post">
|
|
<x-global::forms.text-input name="mattermostWebhookURL" id="mattermostWebhookURL" value="{{ e($mattermostWebhookURL) }}" />
|
|
<br />
|
|
<x-global::forms.button tag="input" inputType="submit" contentRole="primary" :labelText="__('buttons.save')" name="mattermostSave" />
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<br />
|
|
<h4 class="widgettitle title-light"><span class="fa fa-leaf"></span>Slack</h4>
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<img src="https://cdn.cdnlogo.com/logos/s/52/slack.svg" width="200"/>
|
|
</div>
|
|
|
|
<div class="col-md-5">
|
|
{!! __('text.slack_instructions') !!}
|
|
</div>
|
|
<div class="col-md-4">
|
|
<strong>{!! __('label.webhook_url') !!}</strong><br />
|
|
<form action="{{ BASE_URL }}/projects/showProject/{{ $project['id'] }}#integrations" method="post">
|
|
<x-global::forms.text-input name="slackWebhookURL" id="slackWebhookURL" value="{{ e($slackWebhookURL) }}" />
|
|
<br />
|
|
<x-global::forms.button tag="input" inputType="submit" contentRole="primary" :labelText="__('buttons.save')" name="slackSave" />
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<h4 class="widgettitle title-light"><span class="fa fa-leaf"></span>Zulip</h4>
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<img src="{{ BASE_URL }}/dist/images/zulip-org-logo.png" width="200"/>
|
|
</div>
|
|
|
|
<div class="col-md-5">
|
|
{!! __('text.zulip_instructions') !!}
|
|
</div>
|
|
<div class="col-md-4">
|
|
|
|
<form action="{{ BASE_URL }}/projects/showProject/{{ $project['id'] }}#integrations" method="post">
|
|
<strong>{!! __('label.base_url') !!}</strong><br />
|
|
<x-global::forms.text-input name="zulipURL" id="zulipURL" placeholder="{{ __('input.placeholders.zulip_url') }}" value="{{ $zulipHook['zulipURL'] }}" />
|
|
<br />
|
|
<strong>{!! __('label.bot_email') !!}</strong><br />
|
|
<x-global::forms.text-input name="zulipEmail" id="zulipEmail" placeholder="" value="{{ $tpl->escape($zulipHook['zulipEmail']) }}" />
|
|
<br />
|
|
<strong>{!! __('label.botkey') !!}</strong><br />
|
|
<x-global::forms.text-input name="zulipBotKey" id="zulipBotKey" placeholder="" value="{{ $tpl->escape($zulipHook['zulipBotKey']) }}" />
|
|
<br />
|
|
<strong>{!! __('label.stream') !!}</strong><br />
|
|
<x-global::forms.text-input name="zulipStream" id="zulipStream" placeholder="" value="{{ $tpl->escape($zulipHook['zulipStream']) }}" />
|
|
<br />
|
|
<strong>{!! __('label.topic') !!}</strong><br />
|
|
<x-global::forms.text-input name="zulipTopic" id="zulipTopic" placeholder="" value="{{ $tpl->escape($zulipHook['zulipTopic']) }}" />
|
|
<br />
|
|
<x-global::forms.button tag="input" inputType="submit" contentRole="primary" :labelText="__('buttons.save')" name="zulipSave" />
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<h4 class="widgettitle title-light"><span class="fa fa-leaf"></span>Telegram</h4>
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<img src="{{ BASE_URL }}/dist/images/telegram-logo.png" width="130" alt="Telegram logo" />
|
|
</div>
|
|
|
|
<div class="col-md-5">
|
|
{!! __('text.telegram_instructions') !!}
|
|
</div>
|
|
<div class="col-md-4">
|
|
<form action="{{ BASE_URL }}/projects/showProject/{{ $project['id'] }}#integrations" method="post">
|
|
<strong>{!! __('label.botkey') !!}</strong><br />
|
|
<x-global::forms.text-input name="telegramBotToken" id="telegramBotToken" placeholder="" value="{{ $tpl->escape($telegramHook['telegramBotToken']) }}" />
|
|
<br />
|
|
<strong>{!! __('label.telegram_chat_id') !!}</strong><br />
|
|
<x-global::forms.text-input name="telegramChatId" id="telegramChatId" placeholder="{{ __('input.placeholders.telegram_chat_id') }}" value="{{ $tpl->escape($telegramHook['telegramChatId']) }}" />
|
|
<br />
|
|
<strong>{!! __('label.telegram_topic_id') !!}</strong><br />
|
|
<x-global::forms.text-input name="telegramTopicId" id="telegramTopicId" placeholder="{{ __('input.placeholders.telegram_topic_id') }}" value="{{ $tpl->escape($telegramHook['telegramTopicId']) }}" />
|
|
<br />
|
|
<x-global::forms.button tag="input" inputType="submit" contentRole="primary" :labelText="__('buttons.save')" name="telegramSave" />
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Slack webhook --}}
|
|
<h4 class='widgettitle title-light'><span class='fa fa-leaf'></span>Discord</h4>
|
|
<div class='row'>
|
|
<div class='col-md-3'>
|
|
<img src='{{ BASE_URL }}/dist/images/discord-logo.png' width='200'/>
|
|
</div>
|
|
|
|
<div class='col-md-5'>
|
|
{!! __('text.discord_instructions') !!}
|
|
</div>
|
|
<div class="col-md-4">
|
|
<strong>{!! __('label.webhook_url') !!}</strong><br/>
|
|
<form action="{{ BASE_URL }}/projects/showProject/{{ $project['id'] }}#integrations" method="post">
|
|
@for ($i = 1; $i <= 3; $i++)
|
|
@php $discordVarName = 'discordWebhookURL'.$i; $discordVarVal = $$discordVarName ?? ''; @endphp
|
|
<input type="text" name="discordWebhookURL{{ $i }}" id="discordWebhookURL{{ $i }}" placeholder="{{ __('input.placeholders.discord_url') }}" value="{{ e($discordVarVal) }}"/><br/>
|
|
@endfor
|
|
<x-global::forms.button tag="input" inputType="submit" contentRole="primary" :labelText="__('buttons.save')" name="discordSave" />
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div id="todosettings">
|
|
<form action="{{ BASE_URL }}/projects/showProject/{{ $project['id'] }}#todosettings" method="post">
|
|
<ul class="sortableTicketList" id="todoStatusList">
|
|
@foreach ($todoStatus as $key => $ticketStatus)
|
|
<li>
|
|
<div class="ticketBox">
|
|
|
|
<div class="row statusList" id="todostatus-{{ $key }}">
|
|
|
|
<input type="hidden" name="labelKeys[]" id="labelKey-{{ $key }}" class='labelKey' value="{{ $key }}"/>
|
|
<div class="sortHandle">
|
|
<br />
|
|
<span class="fa fa-sort"></span>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<label>{!! __('label.sortindex') !!}</label>
|
|
<input type="text" name="labelSort-{{ $key }}" class="sorter" id="labelSort-{{ $key }}" value="{{ $ticketStatus['sortKey'] }}" style="width:50px;"/>
|
|
</div>
|
|
<div class="col-md-2">
|
|
|
|
<label>{!! __('label.label') !!}</label>
|
|
<input type="text" name="label-{{ $key }}" {{ $key == -1 ? 'readonly' : '' }} id="label-{{ $key }}" value="{{ $ticketStatus['name'] }}" />
|
|
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label>{!! __('label.color') !!}</label>
|
|
<select name="labelClass-{{ $key }}" id="labelClass-{{ $key }}" class="colorChosen">
|
|
<option value="label-purple" class="label-purple" {{ $ticketStatus['class'] == 'label-purple' ? 'selected="selected"' : '' }}><span class="label-purple">{!! __('label.purple') !!}</span></option>
|
|
<option value="label-pink" class="label-pink" {{ $ticketStatus['class'] == 'label-pink' ? 'selected="selected"' : '' }}><span class="label-pink">{!! __('label.pink') !!}</span></option>
|
|
<option value="label-darker-blue" class="label-darker-blue" {{ $ticketStatus['class'] == 'label-darker-blue' ? 'selected="selected"' : '' }}><span class="label-darker-blue">{!! __('label.darker-blue') !!}</span></option>
|
|
<option value="label-info" class="label-info" {{ $ticketStatus['class'] == 'label-info' ? 'selected="selected"' : '' }}><span class="label-info">{!! __('label.dark-blue') !!}</span></option>
|
|
<option value="label-blue" class="label-blue" {{ $ticketStatus['class'] == 'label-blue' ? 'selected="selected"' : '' }}><span class="label-blue">{!! __('label.blue') !!}</span></option>
|
|
<option value="label-dark-green" class="label-dark-green" {{ $ticketStatus['class'] == 'label-dark-green' ? 'selected="selected"' : '' }}><span class="label-dark-green">{!! __('label.dark-green') !!}</span></option>
|
|
<option value="label-success" class="label-success" {{ $ticketStatus['class'] == 'label-success' ? 'selected="selected"' : '' }}><span class="label-success">{!! __('label.green') !!}</span></option>
|
|
<option value="label-warning" class="label-warning" {{ $ticketStatus['class'] == 'label-warning' ? 'selected="selected"' : '' }}><span class="label-warning">{!! __('label.yellow') !!}</span></option>
|
|
<option value="label-brown" class="label-brown" {{ $ticketStatus['class'] == 'label-brown' ? 'selected="selected"' : '' }}><span class="label-brown">{!! __('label.brown') !!}</span></option>
|
|
<option value="label-danger" class="label-danger" {{ $ticketStatus['class'] == 'label-danger' ? 'selected="selected"' : '' }}><span class="label-danger">{!! __('label.dark-red') !!}</span></option>
|
|
<option value="label-important" class="label-important" {{ $ticketStatus['class'] == 'label-important' ? 'selected="selected"' : '' }}><span class="label-important">{!! __('label.red') !!}</span></option>
|
|
<option value="label-default" class="label-default" {{ $ticketStatus['class'] == 'label-default' ? 'selected="selected"' : '' }}><span class="label-default">{!! __('label.grey') !!}</span></option>
|
|
|
|
|
|
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label>{!! __('label.reportType') !!}</label>
|
|
<select name="labelType-{{ $key }}" id="labelType-{{ $key }}">
|
|
<option value="NEW" {{ ($ticketStatus['statusType'] == 'NEW') ? 'selected="selected"' : '' }}>{!! __('status.new') !!}</option>
|
|
<option value="INPROGRESS" {{ ($ticketStatus['statusType'] == 'INPROGRESS') ? 'selected="selected"' : '' }}>{!! __('status.in_progress') !!}</option>
|
|
<option value="DONE" {{ ($ticketStatus['statusType'] == 'DONE') ? 'selected="selected"' : '' }}>{!! __('status.done') !!}</option>
|
|
<option value="NONE" {{ ($ticketStatus['statusType'] == 'NONE') ? 'selected="selected"' : '' }}>{!! __('status.dont_report') !!}</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label for="">{!! __('label.showInKanban') !!}</label>
|
|
<input type="checkbox" name="labelKanbanCol-{{ $key }}" id="labelKanbanCol-{{ $key }}" {{ $ticketStatus['kanbanCol'] ? 'checked="checked"' : '' }}/>
|
|
</div>
|
|
<div class="remove">
|
|
<br />
|
|
@if ($key != -1)
|
|
<a href="javascript:void(0);" onclick="leantime.projectsController.removeStatus({{ $key }})" class="delete"><span class="fa fa-trash"></span></a>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
@if ($key == -1)
|
|
<em>* the archive status is protected cannot be renamed or removed.</em>
|
|
@endif
|
|
</div>
|
|
</li>
|
|
|
|
@endforeach
|
|
</ul>
|
|
|
|
<a href="javascript:void(0);" onclick="leantime.projectsController.addToDoStatus();" class="quickAddLink" style="text-align:left;">{!! __('links.add_status') !!}</a>
|
|
<br />
|
|
<x-global::forms.button tag="input" inputType="submit" :labelText="__('buttons.save')" name="submitSettings" contentRole="primary"/>
|
|
</form>
|
|
</div>
|
|
|
|
<div id="masterdata">
|
|
<h4 class="widgettitle title-light"><span class="fa fa-link"></span> 关联全局主数据</h4>
|
|
<p class="text-muted">关联 BOM / 工艺文件 / 工具清单后,可在项目里追加项目级列(日期、库存、采购数量等),不影响全局主数据。</p>
|
|
|
|
@if (empty($linkedMasters))
|
|
<div class="alert alert-info">本项目尚未关联任何主数据。</div>
|
|
@else
|
|
<div class="table-responsive" style="margin-bottom:20px;">
|
|
<table class="table table-striped table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>类型</th>
|
|
<th>编号</th>
|
|
<th>名称</th>
|
|
<th>版本</th>
|
|
<th style="width:180px;">操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach ($linkedMasters as $ref)
|
|
@php $m = $ref['master'] ?? []; $typeNames = ['bom'=>'BOM','process'=>'工艺文件','tooling'=>'工具清单']; @endphp
|
|
<tr>
|
|
<td><span class="label label-info">{{ $typeNames[$m['type'] ?? 'bom'] ?? 'BOM' }}</span></td>
|
|
<td>{{ $m['bomNo'] ?? '' }}</td>
|
|
<td>{{ $m['productName'] ?? '' }}</td>
|
|
<td>{{ $m['version'] ?? '' }}</td>
|
|
<td>
|
|
<a class="btn btn-xs btn-default" href="{{ BASE_URL }}/bom/refs/{{ $ref['id'] }}">打开</a>
|
|
<button class="btn btn-xs btn-danger btnUnlinkMaster" data-ref-id="{{ $ref['id'] }}">取消关联</button>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@endif
|
|
|
|
@if (! empty($availableMasters))
|
|
<form method="post" action="{{ BASE_URL }}/projects/showProject/{{ $project['id'] }}#masterdata">
|
|
<input type="hidden" name="linkMaster" value="1" />
|
|
<div class="row">
|
|
<div class="col-md-5">
|
|
<select name="masterId" class="form-control">
|
|
@foreach ($availableMasters as $m)
|
|
<option value="{{ $m['id'] }}">{{ $m['typeName'] }} — {{ $m['bomNo'] ?? '' }} {{ $m['productName'] ?? '' }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<x-global::forms.button tag="input" inputType="submit" contentRole="primary" labelText="关联主数据" name="linkMasterSubmit" />
|
|
</div>
|
|
</div>
|
|
</form>
|
|
@else
|
|
<div class="alert alert-warning">没有可关联的全局主数据。请先到「BOM / 工艺文件 / 工具清单」创建主数据。</div>
|
|
@endif
|
|
</div>
|
|
|
|
@dispatchEvent('projectTabsContent')
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- New Status Template -->
|
|
<div class="newStatusTpl" style="display:none;">
|
|
<div class="ticketBox">
|
|
<div class="row statusList" id="todostatus-XXNEWKEYXX">
|
|
<input type="hidden" name="labelKeys[]" id="labelKey-XXNEWKEYXX" class='labelKey' value="XXNEWKEYXX"/>
|
|
<div class="sortHandle">
|
|
<br />
|
|
<span class="fa fa-sort"></span>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<label>{!! __('label.sortindex') !!}</label>
|
|
<input type="text" name="labelSort-XXNEWKEYXX" class="sorter" id="labelSort-XXNEWKEYXX" value="" style="width:50px;"/>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label>{!! __('label.label') !!}</label>
|
|
<input type="text" name="label-XXNEWKEYXX" id="label-XXNEWKEYXX" value="" />
|
|
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label>{!! __('label.color') !!}</label>
|
|
<select name="labelClass-XXNEWKEYXX" id="labelClass-XXNEWKEYXX" class="colorChosen">
|
|
<option value="label-blue" class="label-blue"><span class="label-blue">{!! __('label.blue') !!}</span></option>
|
|
<option value="label-info" class="label-info"><span class="label-info">{!! __('label.dark-blue') !!}</span></option>
|
|
<option value="label-darker-blue" class="label-darker-blue"><span class="label-darker-blue">{!! __('label.darker-blue') !!}</span></option>
|
|
<option value="label-warning" class="label-warning"><span class="label-warning">{!! __('label.yellow') !!}</span></option>
|
|
<option value="label-success" class="label-success"><span class="label-success">{!! __('label.green') !!}</span></option>
|
|
<option value="label-dark-green" class="label-dark-green"><span class="label-dark-green">{!! __('label.dark-green') !!}</span></option>
|
|
<option value="label-important" class="label-important"><span class="label-important">{!! __('label.red') !!}</span></option>
|
|
<option value="label-danger" class="label-danger"><span class="label-danger">{!! __('label.dark-red') !!}</span></option>
|
|
<option value="label-pink" class="label-pink"><span class="label-pink">{!! __('label.pink') !!}</span></option>
|
|
<option value="label-purple" class="label-purple"><span class="label-purple">{!! __('label.purple') !!}</span></option>
|
|
<option value="label-brown" class="label-brown"><span class="label-brown">{!! __('label.brown') !!}</span></option>
|
|
<option value="label-default" class="label-default"><span class="label-default">{!! __('label.grey') !!}</span></option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label>{!! __('label.reportType') !!}</label>
|
|
<select name="labelType-XXNEWKEYXX" id="labelType-XXNEWKEYXX">
|
|
<option value="NEW">{!! __('status.new') !!}</option>
|
|
<option value="INPROGRESS">{!! __('status.in_progress') !!}</option>
|
|
<option value="DONE">{!! __('status.done') !!}</option>
|
|
<option value="NONE">{!! __('status.dont_report') !!}</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label for="">{!! __('label.showInKanban') !!}</label>
|
|
<input type="checkbox" name="labelKanbanCol-XXNEWKEYXX" id="labelKanbanCol-XXNEWKEYXX"/>
|
|
</div>
|
|
<div class="remove">
|
|
<br />
|
|
<a href="javascript:void(0);" onclick="leantime.projectsController.removeStatus('XXNEWKEYXX')" class="delete"><span class="fa fa-trash"></span></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@once @push('scripts')
|
|
<script type='text/javascript'>
|
|
|
|
jQuery(document).ready(function() {
|
|
jQuery("#projectdetails select").chosen();
|
|
|
|
@if (isset($_GET['integrationSuccess']))
|
|
window.history.pushState({},document.title, '{{ BASE_URL }}/projects/showProject/{{ (int) $project['id'] }}');
|
|
@endif
|
|
|
|
jQuery(".dates").datepicker(
|
|
{
|
|
dateFormat: leantime.dateHelper.getFormatFromSettings("dateformat", "jquery"),
|
|
dayNames: leantime.i18n.__("language.dayNames").split(","),
|
|
dayNamesMin: leantime.i18n.__("language.dayNamesMin").split(","),
|
|
dayNamesShort: leantime.i18n.__("language.dayNamesShort").split(","),
|
|
monthNames: leantime.i18n.__("language.monthNames").split(","),
|
|
currentText: leantime.i18n.__("language.currentText"),
|
|
closeText: leantime.i18n.__("language.closeText"),
|
|
buttonText: leantime.i18n.__("language.buttonText"),
|
|
isRTL: leantime.i18n.__("language.isRTL") === "true" ? 1 : 0,
|
|
nextText: leantime.i18n.__("language.nextText"),
|
|
prevText: leantime.i18n.__("language.prevText"),
|
|
weekHeader: leantime.i18n.__("language.weekHeader"),
|
|
firstDay: leantime.i18n.__("language.firstDayOfWeek"),
|
|
}
|
|
);
|
|
|
|
leantime.projectsController.initProjectTabs();
|
|
leantime.projectsController.initDuplicateProjectModal();
|
|
leantime.projectsController.initTodoStatusSortable("#todoStatusList");
|
|
leantime.projectsController.initSelectFields();
|
|
leantime.usersController.initUserEditModal();
|
|
|
|
// 取消关联主数据
|
|
jQuery('.btnUnlinkMaster').on('click', function () {
|
|
var refId = jQuery(this).data('ref-id');
|
|
if (!confirm('确定取消关联该主数据?项目级追加的列和数据将被删除,不影响全局主数据。')) { return; }
|
|
jQuery.ajax({
|
|
url: '{{ BASE_URL }}/bom/api/ref/' + refId,
|
|
method: 'DELETE',
|
|
headers: { 'X-CSRF-TOKEN': jQuery('meta[name="csrf-token"]').attr('content') || '' },
|
|
success: function () { location.reload(); },
|
|
error: function () { alert('取消失败'); }
|
|
});
|
|
});
|
|
|
|
if (window.leantime && window.leantime.tiptapController) {
|
|
leantime.tiptapController.initComplexEditor();
|
|
}
|
|
|
|
});
|
|
|
|
</script>
|
|
@endpush @endonce
|
|
|
|
@endsection
|