동적 탭 관리 기능(회원별 탭 데이터 조회,생성 및 삭제)
This commit is contained in:
parent
2c49552a7b
commit
c9f30c4da3
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.bpgroup.poc.admin.app.tab;
|
||||||
|
|
||||||
|
import com.bpgroup.poc.admin.domain.admin.entity.Admin;
|
||||||
|
import com.bpgroup.poc.admin.domain.admin.service.AdminService;
|
||||||
|
import com.bpgroup.poc.admin.domain.tab.entity.Tab;
|
||||||
|
import com.bpgroup.poc.admin.domain.tab.service.TabAddCommand;
|
||||||
|
import com.bpgroup.poc.admin.domain.tab.service.TabService;
|
||||||
|
import com.bpgroup.poc.admin.web.main.admin.tab.reqres.TabCreate;
|
||||||
|
import com.bpgroup.poc.admin.web.main.admin.tab.reqres.TabDelete;
|
||||||
|
import com.bpgroup.poc.admin.web.main.admin.tab.reqres.TabFind;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Transactional
|
||||||
|
public class TabAppService {
|
||||||
|
|
||||||
|
private final TabService tabService;
|
||||||
|
private final AdminService adminService;
|
||||||
|
|
||||||
|
|
||||||
|
public List<TabFind.Response> findTabList() {
|
||||||
|
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
|
||||||
|
Admin findAdmin = adminService.find(userName).orElseThrow(() -> new IllegalArgumentException("Not found admin"));
|
||||||
|
return tabService.find(findAdmin.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public TabCreate.Response addTab(TabCreate.Request request) {
|
||||||
|
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
|
||||||
|
Admin findAdmin = adminService.find(userName).orElseThrow(() -> new IllegalArgumentException("Not found admin"));
|
||||||
|
Tab tab = tabService.create(
|
||||||
|
TabAddCommand.of(
|
||||||
|
request.getName(),
|
||||||
|
request.getUrl(),
|
||||||
|
findAdmin
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return TabCreate.Response.success(tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TabDelete.Response deleteTab(TabDelete.Request request) {
|
||||||
|
tabService.delete(request.getId());
|
||||||
|
return TabDelete.Response.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.bpgroup.poc.admin.domain.tab.entity;
|
||||||
|
|
||||||
|
import com.bpgroup.poc.admin.domain.BaseEntity;
|
||||||
|
import com.bpgroup.poc.admin.domain.admin.entity.Admin;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Entity
|
||||||
|
@Table(name = "tab")
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
|
public class Tab extends BaseEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "name", length = 100, nullable = false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(name = "url", length = 100, nullable = false)
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name="admin_id", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
||||||
|
private Admin admin;
|
||||||
|
|
||||||
|
private Tab(String name, String url, Admin admin) {
|
||||||
|
this.name = name;
|
||||||
|
this.url = url;
|
||||||
|
this.admin = admin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Tab getNewInstanceForCreateOf(String name, String url, Admin admin) {
|
||||||
|
return new Tab(name, url, admin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.bpgroup.poc.admin.domain.tab.entity;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface TabRepository extends JpaRepository<Tab, Long> {
|
||||||
|
|
||||||
|
List<Tab> findByAdminId(long adminId);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.bpgroup.poc.admin.domain.tab.service;
|
||||||
|
|
||||||
|
import com.bpgroup.poc.admin.domain.admin.entity.Admin;
|
||||||
|
import com.bpgroup.poc.admin.domain.tab.entity.Tab;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class TabAddCommand {
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
private final String url;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final Admin admin;
|
||||||
|
|
||||||
|
public static TabAddCommand of(String name, String url, Admin admin) {
|
||||||
|
return new TabAddCommand(name, url, admin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tab toEntity() {
|
||||||
|
return Tab.getNewInstanceForCreateOf(name, url, admin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.bpgroup.poc.admin.domain.tab.service;
|
||||||
|
|
||||||
|
import com.bpgroup.poc.admin.domain.tab.entity.Tab;
|
||||||
|
import com.bpgroup.poc.admin.domain.tab.entity.TabRepository;
|
||||||
|
import com.bpgroup.poc.admin.web.main.admin.tab.reqres.TabFind;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Validated
|
||||||
|
@Transactional
|
||||||
|
public class TabService {
|
||||||
|
|
||||||
|
private final TabRepository tabRepository;
|
||||||
|
|
||||||
|
public List<TabFind.Response> find(Long adminId) {
|
||||||
|
List<Tab> findTabList = tabRepository.findByAdminId(adminId);
|
||||||
|
return findTabList.stream()
|
||||||
|
.map(TabFind.Response::of)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tab create(
|
||||||
|
@NotNull @Valid TabAddCommand command
|
||||||
|
) {
|
||||||
|
return tabRepository.save(command.toEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete( @NotNull Long id) {
|
||||||
|
tabRepository.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,8 @@ import org.springframework.security.config.Customizer;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||||
|
|
@ -67,7 +69,7 @@ public class SecurityConfig {
|
||||||
|
|
||||||
private void configureAuthorization(HttpSecurity http) throws Exception {
|
private void configureAuthorization(HttpSecurity http) throws Exception {
|
||||||
http.authorizeHttpRequests(c -> c
|
http.authorizeHttpRequests(c -> c
|
||||||
.requestMatchers("/css/**", "/images/**", "/js/**", "/font/**", "/favicon.ico").permitAll()
|
.requestMatchers("/css/**", "/images/**", "/js/**", "/font/**", "/favicon.ico","/admin/tab/**").permitAll()
|
||||||
.requestMatchers("/common/modal/**", "/csrf").permitAll()
|
.requestMatchers("/common/modal/**", "/csrf").permitAll()
|
||||||
.requestMatchers(LOGIN_PATH, LOGOUT_PATH, ERROR_PATH).permitAll()
|
.requestMatchers(LOGIN_PATH, LOGOUT_PATH, ERROR_PATH).permitAll()
|
||||||
.anyRequest()
|
.anyRequest()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.bpgroup.poc.admin.web.main.admin.tab;
|
||||||
|
|
||||||
|
import com.bpgroup.poc.admin.app.tab.TabAppService;
|
||||||
|
import com.bpgroup.poc.admin.web.main.admin.tab.reqres.TabCreate;
|
||||||
|
import com.bpgroup.poc.admin.web.main.admin.tab.reqres.TabDelete;
|
||||||
|
import com.bpgroup.poc.admin.web.main.admin.tab.reqres.TabFind;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/admin")
|
||||||
|
public class TabRestController {
|
||||||
|
|
||||||
|
private final TabAppService tabAppService;
|
||||||
|
|
||||||
|
@GetMapping("/tab/list")
|
||||||
|
public ResponseEntity<?> findTab() {
|
||||||
|
List<TabFind.Response> responses = tabAppService.findTabList();
|
||||||
|
return ResponseEntity.ok(responses);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/tab/add")
|
||||||
|
public ResponseEntity<?> addTab(
|
||||||
|
@RequestBody @Valid TabCreate.Request request ,
|
||||||
|
BindingResult bindingResult
|
||||||
|
) {
|
||||||
|
TabCreate.Response response = tabAppService.addTab(request);
|
||||||
|
return ResponseEntity.ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/tab/delete")
|
||||||
|
public ResponseEntity<?> deleteTab(
|
||||||
|
@RequestBody @Valid TabDelete.Request request
|
||||||
|
) {
|
||||||
|
TabDelete.Response response = tabAppService.deleteTab(request);
|
||||||
|
return ResponseEntity.ok(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.bpgroup.poc.admin.web.main.admin.tab.reqres;
|
||||||
|
|
||||||
|
import com.bpgroup.poc.admin.domain.tab.entity.Tab;
|
||||||
|
import com.bpgroup.poc.admin.web.common.reqres.CommonResponse;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
|
||||||
|
public class TabCreate {
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Request {
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
private String LoginId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
public static class Response extends CommonResponse {
|
||||||
|
public Long id;
|
||||||
|
public static Response success(Tab tab) {
|
||||||
|
Response response = new Response();
|
||||||
|
response.resultCode = "0000";
|
||||||
|
response.resultMessage = "Success";
|
||||||
|
response.id = tab.getId();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Response fail() {
|
||||||
|
Response response = new Response();
|
||||||
|
response.resultCode = "9999";
|
||||||
|
response.resultMessage = "Fail";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.bpgroup.poc.admin.web.main.admin.tab.reqres;
|
||||||
|
|
||||||
|
import com.bpgroup.poc.admin.web.common.reqres.CommonResponse;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
public class TabDelete {
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Request {
|
||||||
|
@NotNull
|
||||||
|
private Long id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
public static class Response extends CommonResponse {
|
||||||
|
|
||||||
|
public static TabDelete.Response success() {
|
||||||
|
TabDelete.Response response = new TabDelete.Response();
|
||||||
|
response.resultCode = "0000";
|
||||||
|
response.resultMessage = "Success";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TabDelete.Response fail(String resultMessage) {
|
||||||
|
TabDelete.Response response = new TabDelete.Response();
|
||||||
|
response.resultCode = "9999";
|
||||||
|
response.resultMessage = resultMessage;
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.bpgroup.poc.admin.web.main.admin.tab.reqres;
|
||||||
|
|
||||||
|
import com.bpgroup.poc.admin.domain.tab.entity.Tab;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TabFind {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
public static class Response {
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private String url;
|
||||||
|
private String loginId;
|
||||||
|
|
||||||
|
public static Response of(Tab tab) {
|
||||||
|
Response response = new Response();
|
||||||
|
response.id = tab.getId();
|
||||||
|
response.name = tab.getName();
|
||||||
|
response.url = tab.getUrl();
|
||||||
|
response.loginId = tab.getAdmin().getLoginId();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -876,7 +876,7 @@ body.login select {
|
||||||
.content {
|
.content {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 70px 30px 50px 30px;
|
padding: 15px 15px 15px 15px;
|
||||||
}
|
}
|
||||||
.con_wrap h3 {
|
.con_wrap h3 {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
@ -904,6 +904,15 @@ body.login select {
|
||||||
|
|
||||||
/* Tab Style */
|
/* Tab Style */
|
||||||
|
|
||||||
|
.close-button {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
color: red;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
.tab-list {
|
.tab-list {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,152 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
<th:block layout:fragment="script"></th:block>
|
<th:block layout:fragment="tabActionScript">
|
||||||
|
<script th:inline="javascript">
|
||||||
|
let tabContentCache = {};
|
||||||
|
|
||||||
|
Reqhelper.reqGetJson('/admin/tab/list', function(data) {
|
||||||
|
data.forEach(function(item) {
|
||||||
|
loadTab(item.id, item.name, item.url);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function loadTab(id,tabName, url) {
|
||||||
|
const newTab = $('<li></li>').addClass('tab-item');
|
||||||
|
const newTabLink = $('<a></a>').addClass('tab-link')
|
||||||
|
.attr('id', `${id}-tab`)
|
||||||
|
.attr('href', `#${id}`)
|
||||||
|
.attr('role', 'tab')
|
||||||
|
.attr('aria-controls', `${id}`)
|
||||||
|
.attr('aria-selected', 'false')
|
||||||
|
.text(tabName)
|
||||||
|
.click(function(event) {
|
||||||
|
openTab(event, id);
|
||||||
|
loadTabContent(id, url);
|
||||||
|
});
|
||||||
|
|
||||||
|
const closeButton = $('<span></span>').addClass('close-button')
|
||||||
|
.text('X')
|
||||||
|
.click(function(event) {
|
||||||
|
$(`#${id}`).remove();
|
||||||
|
$(`#${id}-tab`).parent().remove();
|
||||||
|
event.stopPropagation();
|
||||||
|
Reqhelper.reqPostJson('/admin/tab/delete', {
|
||||||
|
id : id
|
||||||
|
}, function() {
|
||||||
|
console.log('Tab deleted successfully');
|
||||||
|
}, function() {
|
||||||
|
console.log('Failed to delete tab');
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
newTabLink.append(closeButton);
|
||||||
|
newTab.append(newTabLink);
|
||||||
|
$('#myTab').append(newTab);
|
||||||
|
|
||||||
|
const newTabContent = $('<div></div>').addClass('tab-pane')
|
||||||
|
.attr('id', id)
|
||||||
|
.attr('role', 'tabpanel')
|
||||||
|
.attr('aria-labelledby', `${id}-tab`)
|
||||||
|
.on('input', 'input, textarea', function() {
|
||||||
|
tabContentCache[id] = newTabContent.html();
|
||||||
|
});
|
||||||
|
$('#myTabContent').append(newTabContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addTab(tabName,url) {
|
||||||
|
Reqhelper.reqPostJson('/admin/tab/add', {
|
||||||
|
name: tabName,
|
||||||
|
url: url
|
||||||
|
}, function(response) {
|
||||||
|
console.log('Tab created successfully');
|
||||||
|
const tabId = response.id;
|
||||||
|
const newTab = $('<li></li>').addClass('tab-item');
|
||||||
|
const newTabLink = $('<a></a>').addClass('tab-link')
|
||||||
|
.attr('id', `${tabId}-tab`)
|
||||||
|
.attr('href', `#${tabId}`)
|
||||||
|
.attr('role', 'tab')
|
||||||
|
.attr('aria-controls', `${tabId}`)
|
||||||
|
.attr('aria-selected', 'false')
|
||||||
|
.text(tabName)
|
||||||
|
.click(function(event) {
|
||||||
|
openTab(event, tabId);
|
||||||
|
loadTabContent(tabId, url);
|
||||||
|
});
|
||||||
|
|
||||||
|
const closeButton = $('<span></span>').addClass('close-button')
|
||||||
|
.text('X')
|
||||||
|
.click(function(event) {
|
||||||
|
$(`#${tabId}`).remove();
|
||||||
|
$(`#${tabId}-tab`).parent().remove();
|
||||||
|
event.stopPropagation();
|
||||||
|
Reqhelper.reqPostJson('/admin/tab/delete', {
|
||||||
|
id : tabId
|
||||||
|
}, function() {
|
||||||
|
console.log('Tab deleted successfully');
|
||||||
|
}, function() {
|
||||||
|
console.log('Failed to delete tab');
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
newTabLink.append(closeButton);
|
||||||
|
newTab.append(newTabLink);
|
||||||
|
$('#myTab').append(newTab);
|
||||||
|
|
||||||
|
const newTabContent = $('<div></div>').addClass('tab-pane')
|
||||||
|
.attr('id', tabId)
|
||||||
|
.attr('role', 'tabpanel')
|
||||||
|
.attr('aria-labelledby', `${tabId}-tab`)
|
||||||
|
.on('input', 'input, textarea', function() {
|
||||||
|
tabContentCache[tabId] = newTabContent.html();
|
||||||
|
});
|
||||||
|
$('#myTabContent').append(newTabContent);
|
||||||
|
}, function() {
|
||||||
|
console.log('Failed to create tab');
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadTabContent(tabId, url) {
|
||||||
|
if (tabContentCache[tabId]) {
|
||||||
|
$('#' + tabId).html(tabContentCache[tabId]);
|
||||||
|
} else {
|
||||||
|
$.ajax({
|
||||||
|
url: url,
|
||||||
|
type: 'GET',
|
||||||
|
success: function(data) {
|
||||||
|
tabContentCache[tabId] = data;
|
||||||
|
$('#' + tabId).html(data);
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
alert('Failed to load tab content');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openTab(evt, tabId) {
|
||||||
|
$('.tab-pane').css('display', 'none');
|
||||||
|
$('.tab-link').each(function() {
|
||||||
|
$(this).removeClass('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(`#${tabId}`).css('display', 'block');
|
||||||
|
$(evt.currentTarget).addClass('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
$("#myTab").sortable({
|
||||||
|
placeholder: "ui-state-highlight",
|
||||||
|
update: function(event, ui) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$("#myTab").disableSelection();
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</th:block>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
<ul class="sub_menu">
|
<ul class="sub_menu">
|
||||||
<li th:each="menu : ${menuGroup.getMenuChildren()}">
|
<li th:each="menu : ${menuGroup.getMenuChildren()}">
|
||||||
<a th:with="path= ${menu.getUri()}"
|
<a th:with="path= ${menu.getUri()}"
|
||||||
th:classappend="${pathInfo.activeClass(path)}" onclick="addTab(this.textContent)"><span
|
th:classappend="${pathInfo.activeClass(path)}" href="#" th:attr="data-path=${path}" onclick="addTab(this.textContent, this.getAttribute('data-path'))"><span
|
||||||
th:text="${menu.getName()}"></span></a>
|
th:text="${menu.getName()}"></span></a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -16,75 +16,6 @@
|
||||||
</th:block>
|
</th:block>
|
||||||
</th:block>
|
</th:block>
|
||||||
</body>
|
</body>
|
||||||
<th:block layout:fragment="script">
|
<th:block layout:fragment="script" th:replace="~{layout/common.html :: tabActionScript}">
|
||||||
<script th:inline="javascript">
|
|
||||||
let tabIdCounter = 1;
|
|
||||||
|
|
||||||
function addTab(tabName) {
|
|
||||||
const tabId = 'tab' + tabIdCounter++;
|
|
||||||
|
|
||||||
const newTab = $('<li></li>').addClass('tab-item');
|
|
||||||
const newTabLink = $('<a></a>').addClass('tab-link')
|
|
||||||
.attr('id', `${tabId}-tab`)
|
|
||||||
.attr('href', `#${tabId}`)
|
|
||||||
.attr('role', 'tab')
|
|
||||||
.attr('aria-controls', `${tabId}`)
|
|
||||||
.attr('aria-selected', 'false')
|
|
||||||
.text(tabName)
|
|
||||||
.click(function(event) {
|
|
||||||
openTab(event, tabId);
|
|
||||||
loadTabContent(tabName, '/admin/management')
|
|
||||||
});
|
|
||||||
newTab.append(newTabLink);
|
|
||||||
$('#myTab').append(newTab);
|
|
||||||
|
|
||||||
const newTabContent = $('<div></div>').addClass('tab-pane')
|
|
||||||
.attr('id', tabId)
|
|
||||||
.attr('role', 'tabpanel')
|
|
||||||
.attr('aria-labelledby', `${tabId}-tab`)
|
|
||||||
$('#myTabContent').append(newTabContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
function openTab(evt, tabId) {
|
|
||||||
$('.tab-pane').css('display', 'none');
|
|
||||||
$('.tab-link').each(function() {
|
|
||||||
$(this).removeClass('active');
|
|
||||||
});
|
|
||||||
|
|
||||||
$(`#${tabId}`).css('display', 'block');
|
|
||||||
$(evt.currentTarget).addClass('active');
|
|
||||||
}
|
|
||||||
|
|
||||||
$(function() {
|
|
||||||
$("#myTab").sortable({
|
|
||||||
placeholder: "ui-state-highlight",
|
|
||||||
update: function(event, ui) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$("#myTab").disableSelection();
|
|
||||||
});
|
|
||||||
|
|
||||||
function loadTabContent(tabName, url) {
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: 'GET',
|
|
||||||
success: function(response) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function adjustParentDivWidth() {
|
|
||||||
var tabListWidth = $('.tab-list').width();
|
|
||||||
|
|
||||||
$('.parent-div').css('width', tabListWidth + 'px');
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
adjustParentDivWidth();
|
|
||||||
$('.tab-item').on('click', adjustParentDivWidth);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</th:block>
|
</th:block>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue