Ant Design Pro dynamic menu not showing up - ant-design-pro

Following the instruction at https://pro.ant.design/docs/router-and-nav#fetch-menu-from-server
I changed file BasicLayout.tsx as below. Menu is not showing up.
...
const testMenu = [{name:"login", path:"/user/login"}] as any;
const [menuData, setMenuData] = useState([]);
useEffect(() => {
if (dispatch) {
dispatch({
type: 'user/fetchCurrent',
});
}
setMenuData(testMenu)
}, []);
...
menuDataRender={()=>menuData}
...

I was doing same as you and failed as you. Document is still wrong.
And I found getting menu from server has a lot of bug with ant design pro v4. (Maybe I did not know)
So my final decision is to display all menu from /config/config.ts as designed initially.
And get only authorization information from server and set only authority to show only logged in user related menu.
So my solution (not correct answer) is:
I referenced this link. https://umijs.org/docs/runtime-config#patchroutes-routes-
Created file /src/app.tsx and inserted code as follow:
interface PathAndIdsModel {
path: string;
ids: string[];
}
const setAuthority = (routes: any, pathAndIds: PathAndIdsModel[]) => {
routes.forEach((route: any) => {
const found = pathAndIds.find((item) => item.path === route.path);
if (found) {
// eslint-disable-next-line no-param-reassign
route.authority = [...new Set([...(route.authority || []), ...found.ids])];
}
if (route.routes) {
setAuthority(route.routes, pathAndIds);
}
});
};
async function patchRoutes({ routes }) {
const response = await fetch(`https://localhost:44357/authorities`);
const pathAndIds = await response.json();
setAuthority(routes, pathAndIds);
}
export { patchRoutes };
Inserted following code to ASP.Net Core Controller:
[HttpGet("/authorities")]
public IEnumerable<object> Authorities()
{
return new[]
{
new {
Path = "/dashboard/analysis",
Ids = new [] { "user", "admin", },
},
new {
Path = "/dashboard/monitor",
Ids = new [] { "user", "admin", },
},
new {
Path = "/dashboard/workplace",
Ids = new [] { "admin", },
},
new {
Path = "/form/basic-form",
Ids = new [] { "admin", },
},
};
}
/dashboard/workplace and /form/basic-form page will be hidden if logged in as user, but shows if logged in as admin.
I tried to get full routes from server, but failed because of async call, UmiJS did not wait until fetching from server and setting new routes.
So when I fetched routes from server and changed routes, UmiJS already converted icon and component of old routes and my new routes never changed.

Related

Supabase User Returning Null + Auth State Not Saved After Closing App

I am starting to learn React Native and using Supabase with React is pretty different than using it with Flutter. Right now, I have gotten email sign-in/up working and listening for auth changes to switch navigation stacks. I believe my two issues are related because the user/session might not be getting saved when updated.
The first issue is that every time the app is opened, the sign-in screen is shown, even though I signed in before closing it. I tried to set som options, including localStorage but that did not help. Below is my supabaseClient.tsx file.
const options = {
auth: {
localStorage: AsyncStorage as any,
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true,
},
};
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, options);
export { supabase };
The second issue is that I am trying something simple, just showing the displayName that the signed-in user has set on the HomeScreen, but the getUser() and the user from getSession() both return null so I cannot get the user.id. This causes the displayName to be undefined and a blank screen. Below is the code I am using to get the displayName.
export function HomeScreen() {
const [displayName, setDisplayName] = useState();
useEffect(() => {
(async () => {
const user = (await supabase.auth.getSession()).data.session?.user;
console.log("User: " + user);
const { data, error } = await supabase
.from("profiles")
.select()
.eq("uid", user?.id);
if (error === null) {
data!.map((data) => {
const name = data.displayName;
console.log(name);
setDisplayName(name);
});
} else {
console.log(error.message);
}
console.log("Name: " + displayName);
})();
}, [setDisplayName]);
return (
<View>
<Text>{displayName}</Text>
</View>
);
}
I had defined localStorage as any because of a tutorial I saw.
I needed to change this:
const options = {
auth: {
localStorage: AsyncStorage as any,
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true,
},
};
to this:
const options = {
auth: {
localStorage: AsyncStorage,
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true,
},
};

How Do I Update A Database Column In Shopware Via The Administration

I have created an administration page in the Administration and I want to update information in the database when the page is loaded (in Vue js term CREATED). My code below does not do anything and I can not find any error. Help fix my code and how do I get errors from Shopware Administration.
const { Component, Mixin } = Shopware;
import template from './store-settings-page.html.twig'
Component.register('store-settings-page', {
template,
inject: [
'repositoryFactory'
],
metaInfo() {
return {
title: this.$createTitle()
};
},
data: function () {
return {
entity: undefined,
entityId: '4e2891496c4e4587a3a7efe587fc8c80',
}
},
computed: {
storeKeysRepository() {
return this.repositoryFactory.create('store_keys');
},
},
created() {
this.storeKeysRepository
.get(this.entityId, Shopware.Context.api)
.then(entity => {
this.entity = entity;
});
/* const repository = this.storeKeysRepository();
this.entity = repository.create(Shopware.Context.api);
this.entity.name = 'Diekedie';
repository.save(this.entity, Shopware.Context.api);
*/
// a function which is called over the ui
this.entity.name = 'updated';
// sends the request immediately
this.storeKeysRepository
.save(this.entity, Shopware.Context.api)
.then(() => {
// the entity is stateless, the data has be fetched from the server, if required
this.storeKeysRepository
.get(this.entityId, Shopware.Context.api)
.then(entity => {
this.entity = entity;
});
});
},
});
Looks like you're not awaiting the fetch request meaning your entity would still be undefined when it reaches the save call on the repository.
You should move the save call inside the chained method of the first request. Also unless you have some fields which are indexed or computed server side, you might not need to refetch the entity after the successful save call.
this.storeKeysRepository.get(this.entityId, Shopware.Context.api).then((entity) => {
this.entity = entity;
this.entity.name = 'updated';
this.storeKeysRepository.save(this.entity, Shopware.Context.api);
});

Why useQuery refetch() doesn't work sometimes?

I use react-native with graphql.
I have a query and tried to use refetch.
const { data: updatePhoto, refetch } = useQuery(SEE_PHOTO_QUERY, {
variables: {
id: photoId,
},
});
when after I edit my comment, I want to refetch this query and put it on setState in order to change UI.
const onEditValid = async ({ comments }) => {
const commentId = await AsyncStorage.getItem("#commentId");
await editCommentMutation({
variables: {
id: parseInt(commentId),
payload: comments,
},
update: updateEditComment,
});
};
const updateEditComment = async (cache, result) => {
const {
data: {
editComment: { error, ok, id },
},
} = result;
if (ok) {
const commentId = await AsyncStorage.getItem("#commentId");
const { comments } = getValues();
await textRef.current.clear();
await refetch();
setState(updatePhoto);
await cache.modify({
id: `Comment:${commentId}`,
fields: {
payload(prev) {
return comments;
},
},
});
}
};
But UI doesn't change.
I tried to change UI by modifying cache and refetching data. But both fails for a week.. :(
I also raised the question about fail of cache modify
=> React Native: `cache.modity` doesn't work
But no one answers.
I really need your help.. please help me

How to use realm with async fetch request?

I have meet this situation for my requirements:
step 1. save data to local db which in the mobile phone (realm)
step 2. upload the local data to the server, and the server will return the data ids if success
step 3. delete the records in local db by the returned ids which get by step2
Realm.open({schema:[MySchame],encryptionKey:getRealmKey()})
.then(realm =>{
realm.write(() => {
// 1. get all step data from db
let objetcs = realm.objects('MySchema');
// 2. upload obtained data to server
if(objetcs.length > 0){
let recordArr = [];
for (let o of steps){
recordArr.push(o.get());
}
uploadDataToServer(recordArr,(res)=>{
//3. filter the uploaded steps and delete them
let uploadedSteps = realm.objects('MySchema').filtered('id=$0',res.id);
if(uploadedSteps.length > 0){
realm.delete(uploadedSteps);
}
});
}
});
realm.close();
})
.catch(error =>{
console.log(error);
});
but this is not works as expected, it seems DB is closed too early than networks success callback.
Thanks for any ideas.
Finally ,I use realm like this:
let realm = new Realm({schema:[JOB_SCHEMA.jobTrack],encryptionKey:getRealmKey()});
let objects = realm.objects('JobTrack');
realm.beginTransaction();
realm.delete(objects);
realm.commitTransaction();
realm.close();
First create a service like one below
import repository from "./realmConfig";
let CatalogsService = {
findAll: function () {
return repository.objects("CatalogsModel");
},
save: function (catalogs) {
repository.write(() => {
repository.create("CatalogsModel", catalogs);
});
},
delete: function () {
repository.write(() => {
let all = repository.objects("CatalogsModel");
repository.delete(all);
});
},
update: function (catalogs, callback) {
if (!callback) return;
repository.write(() => {
callback();
catalogs.updatedAt = new Date();
});
}
};
module.exports = CatalogsService;
where my realmConfig file is as
import Realm from "realm";
class CatalogsModel extends Realm.Object { }
CatalogsModel.schema = {
name: "CatalogsModel",
primaryKey: "id",
properties: {
id: "string",
name: "string",
url: "string",
status: "int"
}
};
class OffersModel extends Realm.Object { }
OffersModel.schema = {
name: "OffersModel",
primaryKey: "id",
properties: {
id: "string",
name: "string",
url: "string",
status: "int",
machineId: "string",
machineName: "string"
}
};
export default new Realm({
schema: [CatalogsModel, OffersModel],
schemaVersion: 1,
deleteRealmIfMigrationNeeded: true
});
Now import Service.js where you are calling async server call and do your job. For reference see below code
import CatalogService from './path/to/CatalogService .js'
//get objects
var catalogs = CatalogsService.findAll();
// fire async function , I prefer axios for network calls
Axios.post("SERVER_URL", {
data: catalogs
})
.then(function (response) {
if (response.success)
CatalogsService.delete()
}
I assume you can easily modify findAll() and delete() method as per your need

Realm "observer.next create #[native code]" exception

I am trying to fetch data with apollo and then write it to realm. I have created a js file that I know works, because it has worked before. But, when I try to write to a particular model I get an error message. More details as follows:
Code (Not entire code) LocationQuery.js:
const realm = new Realm({ schema: [testBuilding1], schemaVersion: 1 });
let buildingTypeArray = [];
const temp = [];
class LocationQuery extends Component {
static get propTypes() {
return {
data: React.PropTypes.shape({
loading: React.PropTypes.bool,
error: React.PropTypes.object,
sites: React.PropTypes.array,
}).isRequired,
};
}
render() {
if (this.props.data.loading) {
return (null);
}
if (this.props.data.error) {
return (<Text>An unexpected error occurred</Text>);
}
if (this.props.data.sites) {
this.props.data.sites.map((value) => {
buildingTypeArray.push(value.locations);
});
buildingTypeArray.forEach((locationValues) => {
realm.write(() => {
realm.create('testBuilding1', {
building: '273',
});
});
});
}
return null;
}
}
const locationQueryCall = gql`
query locationQueryCall($id: String!){
sites(id: $id){
locations {
building
type
}
}
}`;
const ViewWithData = graphql(locationQueryCall, {
options: props => ({
variables: {
id: 'SCH1',
},
}),
})(LocationQuery);
export default connect(mapStateToProp)(ViewWithData);
The error I get is a big red screen that read:
console.error: "Error in observe.next.... blah blah blah"
The Model I am using:
export const testBuilding1 = {
name: 'testBuilding1',
properties: {
building: 'string',
},
};
The weird thing is that the code works when I use this model:
export const locationScene = {
name: 'locationScene',
properties: {
building: 'string',
},
};
I am calling LocationQuery.js in another piece of code passing it through at render.
Thank you in advance for the help!