diff --git a/api/src/Kurs.Platform.Application/Tenants/PlatformTenantAppService.cs b/api/src/Kurs.Platform.Application/Tenants/PlatformTenantAppService.cs index adce6eb4..77b40a1e 100644 --- a/api/src/Kurs.Platform.Application/Tenants/PlatformTenantAppService.cs +++ b/api/src/Kurs.Platform.Application/Tenants/PlatformTenantAppService.cs @@ -37,6 +37,19 @@ public class PlatformTenantAppService : TenantAppService, IPlatformTenantAppServ LocalizationResource = typeof(PlatformResource); } + public override Task GetAsync(Guid id) + { + return base.GetAsync(id); + } + + [AllowAnonymous] + public async Task GetByNameAsync(string name) + { + return ObjectMapper.Map( + await TenantRepository.FindByNameAsync(name) + ); + } + [AllowAnonymous] public override Task> GetListAsync(GetTenantsInput input) => base.GetListAsync(input); diff --git a/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json b/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json index b34e4733..33c12539 100644 --- a/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json +++ b/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json @@ -6754,7 +6754,7 @@ "ParentName": null, "DisplayName": "App.ForumManagement", "IsEnabled": true, - "MultiTenancySide": 3 + "MultiTenancySide": 2 }, { "GroupName": "App.Setting", @@ -7796,14 +7796,6 @@ "IsEnabled": true, "MultiTenancySide": 2 }, - { - "GroupName": "App.ForumManagement", - "Name": "App.ForumManagement.Publish", - "ParentName": "App.ForumManagement", - "DisplayName": "Publish", - "IsEnabled": true, - "MultiTenancySide": 3 - }, { "GroupName": "App.ForumManagement", "Name": "App.ForumManagement.Create", @@ -7835,6 +7827,14 @@ "DisplayName": "Update", "IsEnabled": true, "MultiTenancySide": 2 + }, + { + "GroupName": "App.ForumManagement", + "Name": "App.ForumManagement.Publish", + "ParentName": null, + "DisplayName": "Publish", + "IsEnabled": true, + "MultiTenancySide": 3 } ], "Sectors": [ diff --git a/ui/dev-dist/sw.js b/ui/dev-dist/sw.js index 0b99fe8b..9f2efa82 100644 --- a/ui/dev-dist/sw.js +++ b/ui/dev-dist/sw.js @@ -82,7 +82,7 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict'; "revision": "3ca0b8505b4bec776b69afdba2768812" }, { "url": "index.html", - "revision": "0.m83v8d1s4bo" + "revision": "0.3kkdvt11rc8" }], {}); workbox.cleanupOutdatedCaches(); workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { diff --git a/ui/src/proxy/admin/tenant/tenant.service.ts b/ui/src/proxy/admin/tenant/tenant.service.ts index bb087b6e..0b49b7d1 100644 --- a/ui/src/proxy/admin/tenant/tenant.service.ts +++ b/ui/src/proxy/admin/tenant/tenant.service.ts @@ -9,6 +9,12 @@ export const getTenants = (skipCount = 0, maxResultCount = 10) => url: `/api/app/platform-tenant?skipCount=${skipCount}&maxResultCount=${maxResultCount}`, }) +export const getTenantByName = (name: string) => + apiService.fetchData({ + method: 'GET', + url: `/api/app/platform-tenant/by-name?name=${encodeURIComponent(name)}`, + }) + export const getTenantById = (id: string) => apiService.fetchData({ method: 'GET', diff --git a/ui/src/services/authApi.service.ts b/ui/src/services/authApi.service.ts index 279a026c..5ce2c6b3 100644 --- a/ui/src/services/authApi.service.ts +++ b/ui/src/services/authApi.service.ts @@ -49,9 +49,9 @@ authApiService.interceptors.response.use( ) authApiService.interceptors.request.use(async (config) => { - const { tenantId } = store.getState().auth - if (tenantId) { - config.headers['__tenant'] = tenantId + const { currentTenantName } = store.getState().locale + if (currentTenantName) { + config.headers['__tenant'] = currentTenantName } else { config.headers.delete('__tenant') } diff --git a/ui/src/services/forumService.ts b/ui/src/services/forumService.ts index 9c47d535..945d8911 100644 --- a/ui/src/services/forumService.ts +++ b/ui/src/services/forumService.ts @@ -120,7 +120,7 @@ class ForumService { const response = await apiService.fetchData({ url: '/api/app/forum/category', method: 'POST', - data, + data: {...data}, }) return response.data } @@ -181,7 +181,7 @@ class ForumService { const response = await apiService.fetchData({ url: '/api/app/forum/topic', method: 'POST', - data, + data: {...data}, }) return response.data } @@ -288,7 +288,7 @@ class ForumService { const response = await apiService.fetchData({ url: '/api/app/forum/post', method: 'POST', - data, + data: {...data}, }) return response.data } diff --git a/ui/src/services/platformApi.service.ts b/ui/src/services/platformApi.service.ts index f898664a..b73d8631 100644 --- a/ui/src/services/platformApi.service.ts +++ b/ui/src/services/platformApi.service.ts @@ -34,9 +34,9 @@ platformApiService.interceptors.request.use(async (config) => { config.headers['Accept-Language'] = cultureName } - const { tenantId } = state.auth - if (tenantId) { - config.headers['__tenant'] = tenantId + const { currentTenantName } = state.locale + if (currentTenantName) { + config.headers['__tenant'] = currentTenantName } else { config.headers.delete('__tenant') } diff --git a/ui/src/store/auth.model.ts b/ui/src/store/auth.model.ts index 42df0109..bc7785da 100644 --- a/ui/src/store/auth.model.ts +++ b/ui/src/store/auth.model.ts @@ -21,7 +21,10 @@ export interface AuthStoreModel { name: string avatar?: string } - tenantId?: string + tenant?: { + tenantId?: string + tenantName?: string + } } export interface AuthStoreActions { @@ -36,7 +39,9 @@ export interface AuthStoreActions { user: { setUser: Action } - setTenantId: Action + tenant: { + setTenant: Action, AuthStoreModel['tenant']> + } } export type AuthModel = AuthStoreModel & AuthStoreActions @@ -52,7 +57,10 @@ export const initialState: AuthStoreModel = { name: '', avatar: '', }, - tenantId: undefined, + tenant: { + tenantId: '', + tenantName: '', + }, } export const authModel: AuthModel = { @@ -70,9 +78,10 @@ export const authModel: AuthModel = { state.user.userName = payload.user.userName state.user.authority = payload.user.authority state.user.email = payload.user.email - state.user.avatar = AVATAR_URL(payload.user.id, state.tenantId)+ `?${dayjs().unix()}` + state.user.avatar = AVATAR_URL(payload.user.id, state.tenant?.tenantId) + `?${dayjs().unix()}` }), - signOut: action((state) => ({ ...initialState, tenantId: state.tenantId })), + signOut: action(() => ({ ...initialState })), + // signOut: action((state) => ({ ...initialState, tenantId: state.tenant?.tenantId })), onSignInAndOut: thunkOn( (actions, storeActions) => [storeActions.auth.signIn, storeActions.auth.signOut], async (actions, payload, { getStoreActions }) => { @@ -94,8 +103,11 @@ export const authModel: AuthModel = { state.avatar = payload.avatar }), }, - tenantId: initialState.tenantId, - setTenantId: action((state, payload) => { - state.tenantId = payload - }), + tenant: { + ...initialState.tenant, + setTenant: action((state, payload) => { + state.tenantId = payload?.tenantId + state.tenantName = payload?.tenantName + }), + }, } diff --git a/ui/src/store/locale.model.ts b/ui/src/store/locale.model.ts index b86fb193..97f3e318 100644 --- a/ui/src/store/locale.model.ts +++ b/ui/src/store/locale.model.ts @@ -6,19 +6,22 @@ import { Injections, StoreModel } from '.' export interface LocaleStoreModel { currentLang: string currentUiVersion: string | undefined + currentTenantName?: string } export interface LocaleStoreActions { setLang: Action onSetLang: ThunkOn setUiVersion: Action + setTenantName: Action } export type LocaleModel = LocaleStoreModel & LocaleStoreActions const initialState: LocaleStoreModel = { currentLang: appConfig.locale, - currentUiVersion: appConfig.uiVersion + currentUiVersion: appConfig.uiVersion, + currentTenantName: undefined } export const localeModel: LocaleModel = { @@ -36,4 +39,7 @@ export const localeModel: LocaleModel = { setUiVersion: action((state, payload) => { state.currentUiVersion = payload }), + setTenantName: action((state, payload) => { + state.currentTenantName = payload + }), } diff --git a/ui/src/views/auth/Login.tsx b/ui/src/views/auth/Login.tsx index 5f1e0ea2..119c490a 100644 --- a/ui/src/views/auth/Login.tsx +++ b/ui/src/views/auth/Login.tsx @@ -9,6 +9,7 @@ import { FormContainer, FormItem } from '@/components/ui/Form' import Input from '@/components/ui/Input' import PlatformLoginResultType from '@/constants/login.result.enum' import { ROUTES_ENUM } from '@/constants/route.constant' +import { getTenantByName } from '@/proxy/admin/tenant/tenant.service' import { useStoreActions, useStoreState } from '@/store' import useAuth from '@/utils/hooks/useAuth' import { useLocalization } from '@/utils/hooks/useLocalization' @@ -43,7 +44,10 @@ const validationSchema = Yup.object().shape({ const Login = () => { const navigate = useNavigate() const isMultiTenant = useStoreState((a) => a.abpConfig.config?.multiTenancy.isEnabled) - const { setTenantId } = useStoreActions((a) => a.auth) + const { setTenant } = useStoreActions((a) => a.auth.tenant) + + const tenantName = useStoreState((state) => state.locale.currentTenantName) + const { setTenantName } = useStoreActions((actions) => actions.locale) const [message, setMessage] = useState('') const [error, setError] = useTimeOutMessage(300000) @@ -164,13 +168,36 @@ const Login = () => { setShowCaptcha(false) setError('') setMessage('') + + //Tenant belirlenmişse + fetchDataByName(tenantName || '') } setSubmitting(false) } + const fetchDataByName = async (name: string) => { + if (name) { + const response = await getTenantByName(name) + + if (response.data) { + setTenant({ tenantId: response.data.id, tenantName: response.data.name }) + } else { + setTenant(undefined) + } + } else { + setTenant(undefined) + } + } + const subDomainName = getSubdomain() - const tenantId = useStoreState((a) => a.auth.tenantId) ?? subDomainName + useEffect(() => { + if (subDomainName) { + setTenantName(subDomainName) + fetchDataByName(subDomainName) + } + }, [subDomainName]) + const tenantStyle: React.CSSProperties | undefined = subDomainName && subDomainName !== defaultSubDomain ? { @@ -184,23 +211,6 @@ const Login = () => { } : undefined - const { config } = useStoreState((state) => state.abpConfig) - const { setLang } = useStoreActions((actions) => actions.locale) - const currentCulture = config?.localization?.currentCulture?.cultureName - - const languageList = config?.localization.languages - - useEffect(() => { - if (!isMultiTenant) return - - const subDomainName = getSubdomain() - if (subDomainName?.toUpperCase() === defaultSubDomain) { - setTenantId('') - } else { - setTenantId(subDomainName || '') - } - }, [isMultiTenant]) - return ( {
setTenantId(e.target.value)} + value={tenantName} + onChange={(e) => setTenantName(e.target.value)} style={tenantStyle} aria-hidden={subDomainName && subDomainName !== defaultSubDomain ? 'true' : 'false'} /> diff --git a/ui/src/views/auth/Settings/components/Profile.tsx b/ui/src/views/auth/Settings/components/Profile.tsx index d31a9fac..c5345722 100644 --- a/ui/src/views/auth/Settings/components/Profile.tsx +++ b/ui/src/views/auth/Settings/components/Profile.tsx @@ -109,7 +109,7 @@ const Profile = () => { setUser({ ...auth.user, name: `${resp.data.name} ${resp.data.surname}`.trim(), - avatar: AVATAR_URL(auth.user.id, auth.tenantId) + `?${dayjs().unix()}`, + avatar: AVATAR_URL(auth.user.id, auth.tenant.tenantId) + `?${dayjs().unix()}`, }) toast.push(, { diff --git a/ui/src/views/forum/useForumData.ts b/ui/src/views/forum/useForumData.ts index e0e61d62..24cc7f02 100644 --- a/ui/src/views/forum/useForumData.ts +++ b/ui/src/views/forum/useForumData.ts @@ -1,5 +1,10 @@ import { ForumCategory, ForumPost, ForumTopic } from '@/proxy/forum/forum' -import { forumService } from '@/services/forumService' +import { + CreateCategoryRequest, + CreatePostRequest, + CreateTopicRequest, + forumService, +} from '@/services/forumService' import { useState, useEffect } from 'react' export function useForumData() { @@ -56,15 +61,7 @@ export function useForumData() { } // Category operations - const createCategory = async (categoryData: { - name: string - slug: string - description: string - icon: string - displayOrder: number - isActive: boolean - isLocked: boolean - }) => { + const createCategory = async (categoryData: CreateCategoryRequest) => { try { setLoading(true) const newCategory = await forumService.createCategory(categoryData) @@ -99,7 +96,7 @@ export function useForumData() { await loadCategories() // refresh after update } - const updateCategoryActiveState = async (id: string) => { + const updateCategoryActiveState = async (id: string) => { await forumService.updateCategoryActiveState(id) await loadCategories() // refresh after update } @@ -124,13 +121,7 @@ export function useForumData() { } // Topic operations - const createTopic = async (topicData: { - title: string - content: string - categoryId: string - isPinned?: boolean - isLocked?: boolean - }) => { + const createTopic = async (topicData: CreateTopicRequest) => { try { setLoading(true) const newTopic = await forumService.createTopic(topicData) @@ -273,11 +264,7 @@ export function useForumData() { } // Post operations - const createPost = async (postData: { - topicId: string - content: string - parentPostId?: string - }) => { + const createPost = async (postData: CreatePostRequest) => { try { setLoading(true) const newPost = await forumService.createPost(postData)